Initial commit
This commit is contained in:
commit
49fdf75c41
11 changed files with 474 additions and 0 deletions
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
test/output/
|
||||
test/*
|
||||
!test/*.c
|
||||
!test/Makefile
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.so.*
|
||||
*.core
|
93
Makefile
Normal file
93
Makefile
Normal file
|
@ -0,0 +1,93 @@
|
|||
# _,.---._ .-._ .--.-. ,--.--------.
|
||||
# _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
# /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
# |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
# |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
# |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
# |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
# |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
# `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
# _ __ ,---. .-._ .=-.-. _,.----.
|
||||
# .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
# /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
# |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
# |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
# |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
# |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
# /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
# `--`---' `--` `--`./ `--``--`-`
|
||||
#
|
||||
# @(#)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
|
||||
|
||||
libname = epoch
|
||||
|
||||
CFLAGS += -Wall -Werror
|
||||
CFLAGS += -Iinclude
|
||||
CFLAGS += -fPIC
|
||||
|
||||
hdrs += include/epoch.h
|
||||
|
||||
srcs += epoch.c
|
||||
srcs += month.c
|
||||
srcs += weekday.c
|
||||
srcs += year.c
|
||||
srcs += zone.c
|
||||
|
||||
objs = $(srcs:.c=.o)
|
||||
|
||||
all: shared static
|
||||
|
||||
shared: lib$(libname).so
|
||||
|
||||
static: lib$(libname).a
|
||||
|
||||
$(srcs): $(hdrs)
|
||||
|
||||
lib$(libname).a: $(objs)
|
||||
$(AR) rcs $@ $?
|
||||
|
||||
lib$(libname).so: $(objs)
|
||||
$(CC) -shared -o $@ $? $(LIBS)
|
||||
|
||||
install: install_include install_shared install_static
|
||||
|
||||
install_include: include/$(libname).h
|
||||
@[ -d $(includedir) ] || install -d $(includedir)
|
||||
install -m644 include/$(libname).h $(includedir)/
|
||||
|
||||
install_static: lib$(libname).a
|
||||
@[ -d $(libdir) ] || install -d $(libdir)
|
||||
install -m644 lib$(libname) $(libdir)/
|
||||
|
||||
install_shared: lib$(libname).so
|
||||
@[ -d $(libdir) ] || install -d $(libdir)
|
||||
install -m755 lib$(libname).so $(libdir)/
|
||||
|
||||
test: lib$(libname).a
|
||||
$(MAKE) -C test
|
||||
|
||||
testclean:
|
||||
$(MAKE) -C test clean
|
||||
|
||||
clean:
|
||||
rm -rf *.a *.so *.o haggis
|
||||
$(MAKE) -C test clean
|
||||
|
||||
.PHONY: all shared static clean install install_include install_static \
|
||||
install_shared testclean test
|
3
compile_flags.txt
Normal file
3
compile_flags.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
-I
|
||||
include
|
||||
|
0
config.mk
Normal file
0
config.mk
Normal file
0
epoch.c
Normal file
0
epoch.c
Normal file
88
include/epoch.h
Normal file
88
include/epoch.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
#ifndef LIBEPOCH_H
|
||||
#define LIBEPOCH_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SECONDS_PER_MINUTE 60
|
||||
#define SECONDS_PER_HOUR 60 * 60
|
||||
#define SECONDS_PER_DAY 60 * 60 * 24
|
||||
|
||||
typedef enum {
|
||||
normalYear,
|
||||
leapYear,
|
||||
} yearTag;
|
||||
|
||||
typedef struct {
|
||||
yearTag tag;
|
||||
uint32_t year;
|
||||
} Year;
|
||||
|
||||
typedef enum {
|
||||
January = 1,
|
||||
February = 2,
|
||||
March = 3,
|
||||
April = 4,
|
||||
May = 5,
|
||||
June = 6,
|
||||
July = 7,
|
||||
August = 8,
|
||||
September = 9,
|
||||
October = 10,
|
||||
November = 11,
|
||||
December = 12,
|
||||
} Month;
|
||||
|
||||
typedef enum {
|
||||
Thursday = 0,
|
||||
Friday = 1,
|
||||
Saturday = 2,
|
||||
Sunday = 3,
|
||||
Monday = 4,
|
||||
Tuesday = 5,
|
||||
Wednesday = 6,
|
||||
} Weekday;
|
||||
|
||||
typedef enum {
|
||||
Offset,
|
||||
UTC,
|
||||
} timeZoneTag;
|
||||
|
||||
typedef enum {
|
||||
Positive,
|
||||
Negative,
|
||||
} offsetSign;
|
||||
|
||||
typedef struct {
|
||||
offsetSign sign;
|
||||
uint8_t hours;
|
||||
uint8_t minutes;
|
||||
} TzOffset;
|
||||
|
||||
typedef struct {
|
||||
timeZoneTag tag;
|
||||
TzOffset *offset;
|
||||
} TimeZone;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
const char* weekdayName(Weekday day);
|
||||
const char* weekdayAbbr(Weekday day);
|
||||
int parseWeekday(const char *s);
|
||||
|
||||
int offsetNew(TzOffset *offs, offsetSign sign, uint8_t hours, uint8_t minutes);
|
||||
void printTz(TimeZone *zone);
|
||||
|
||||
#endif // !LIBEPOCH_H
|
69
month.c
Normal file
69
month.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
#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) {
|
||||
case January:
|
||||
case March:
|
||||
case May:
|
||||
case July:
|
||||
case August:
|
||||
case October:
|
||||
case December:
|
||||
return 31;
|
||||
case February:
|
||||
switch (year->tag) {
|
||||
case leapYear:
|
||||
return 28;
|
||||
default:
|
||||
return 29;
|
||||
}
|
||||
default:
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t monthGetSeconds(Month month, Year *year) {
|
||||
return (int64_t)monthGetDays(month, year) * SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
int monthIncrement(Month *month) {
|
||||
if (*month == December)
|
||||
return 1;
|
||||
else
|
||||
*month += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int monthDecrement(Month *month) {
|
||||
if (*month == January)
|
||||
return 1;
|
||||
else
|
||||
*month -= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *MonthNames[] = { "January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December" };
|
||||
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* monthAbbr(Month month) {
|
||||
return MonthAbbrs[month - 1];
|
||||
}
|
||||
|
||||
int parseMonth(const char *s) {
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (strncasecmp(s, MonthAbbrs[i], 4) == 0 || strncasecmp(s, MonthNames[i], 10) == 0)
|
||||
return i + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
110
test/Makefile
Normal file
110
test/Makefile
Normal file
|
@ -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/*
|
24
weekday.c
Normal file
24
weekday.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "epoch.h"
|
||||
#include <strings.h>
|
||||
|
||||
const char *WeekdayNames[] = { "Thursday", "Friday", "Saturday", "Sunday", "Monday",
|
||||
"Tuesday", "Wednesday" };
|
||||
const char *WeekdayAbbrs[] = { "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed" };
|
||||
|
||||
const char* weekdayName(Weekday day) {
|
||||
return WeekdayNames[day];
|
||||
}
|
||||
|
||||
const char* weekdayAbbr(Weekday day) {
|
||||
return WeekdayAbbrs[day];
|
||||
}
|
||||
|
||||
int parseWeekday(const char *s) {
|
||||
int i;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (strncasecmp(s, WeekdayAbbrs[i], 4) == 0 || strncasecmp(s, WeekdayNames[i], 10) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
45
year.c
Normal file
45
year.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <stdint.h>
|
||||
#include "epoch.h"
|
||||
|
||||
void yearNew(Year *year, int32_t inner) {
|
||||
year->year = inner;
|
||||
if (inner % 4 == 0 && (inner % 100 != 0 || inner % 400 == 0))
|
||||
year->tag = leapYear;
|
||||
else
|
||||
year->tag = normalYear;
|
||||
}
|
||||
|
||||
uint16_t yearGetDays(Year *year) {
|
||||
switch (year->tag) {
|
||||
case normalYear:
|
||||
return 365;
|
||||
case leapYear:
|
||||
return 366;
|
||||
default:
|
||||
return 365;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t yearGetSeconds(Year *year) {
|
||||
return (int64_t)yearGetDays(year) * SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
int32_t yearGetInner(Year *year) {
|
||||
return year->year;
|
||||
}
|
||||
|
||||
void yearIncrement(Year *year) {
|
||||
year->year += 1;
|
||||
if (year->year % 4 == 0 && (year->year % 100 != 0 || year->year % 400 == 0))
|
||||
year->tag = leapYear;
|
||||
else
|
||||
year->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;
|
||||
else
|
||||
year->tag = normalYear;
|
||||
}
|
33
zone.c
Normal file
33
zone.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "epoch.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
int offsetNew(TzOffset *offs, offsetSign sign, uint8_t hours, uint8_t minutes) {
|
||||
if (offs == NULL) return 1;
|
||||
if (hours > 12) return 2;
|
||||
if (hours > 11 && minutes > 0) return 3;
|
||||
if (minutes > 59) return 4;
|
||||
offs->sign = sign;
|
||||
offs->hours = hours;
|
||||
offs->minutes = minutes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printTz(TimeZone *zone) {
|
||||
switch (zone->tag) {
|
||||
case UTC: printf("UTC");
|
||||
case Offset:
|
||||
switch (zone->offset->sign) {
|
||||
case Positive:
|
||||
puts("+");
|
||||
break;
|
||||
case Negative:
|
||||
puts("-");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
printf("%.2u:%.2u", zone->offset->hours, zone->offset->minutes);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue