aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitignore3
-rw-r--r--Makefile44
-rw-r--r--src/logerr.c67
-rw-r--r--src/logerr.h34
-rw-r--r--src/remembering.c5
-rw-r--r--src/tests-lib.c29
-rw-r--r--src/tests-lib.h13
-rw-r--r--src/unit-test.h8
-rwxr-xr-x[-rw-r--r--]tests/assert-catgets.sh67
-rwxr-xr-x[-rw-r--r--]tests/c-lint.sh65
10 files changed, 318 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 1035d7f..099f6f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
/public/
/tests/test-profiles/
/src/remembering
+/src/config.h
+*.o
+*.to
/remembering
/remembering-tests
/run-tests
diff --git a/Makefile b/Makefile
index 10351f0..903b94a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,4 @@
.POSIX:
-DEFS = -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"'
PREFIX = /usr/local
MANPREFIX = '$(PREFIX)/share/man'
VERSION = 0.2.1
@@ -11,12 +10,18 @@ CONTRIBLANGS =
.SUFFIXES:
-.SUFFIXES: .in
+.SUFFIXES: .in .to .c .o
.in:
sed -e 's:@VERSION@:$(VERSION):g' -e 's:@DATE@:$(DATE):g' < $< > $@
if [ -x $< ]; then chmod +x $@; fi
+.c.o:
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+.c.to:
+ $(CC) $(CFLAGS) -DTEST -o $@ -c $<
+
manpages.en.in = \
doc/remembering.en.1.in \
@@ -30,18 +35,45 @@ manpages.in = $(manpages.en.in) \
doc/remembering.eo.5.in
manpages = $(manpages.in:.in=)
+sources = \
+ src/logerr.c \
+ src/remembering.c
+objects = $(sources:.c=.o)
+t-sources = $(sources) src/tests-lib.c
+t-objects = $(t-sources:.c=.to)
+
all: src/remembering remembering $(manpages)
-remembering: src/remembering.c
- $(CC) $(CFLAGS) $(DEFS) $(LDFLAGS) -o $@ $? $(LDLIBS)
+remembering: $(objects)
+ $(CC) $(LDFLAGS) -o $@ $(objects) $(LDLIBS)
+
+remembering-tests: $(t-objects)
+ $(CC) $(LDFLAGS) -o $@ $(t-objects) $(LDLIBS)
+
+src/config.h:
+ printf '#ifndef REMEMBERING_CONFIG_H\n' >> $@
+ printf '#define REMEMBERING_CONFIG_H\n' >> $@
+ printf '\n' >> $@
+ printf '#define _POSIX_C_SOURCE 200809L\n' >> $@
+ printf '#define VERSION "$(VERSION)"\n' >> $@
+ printf '#define DATE "$(DATE)"\n' >> $@
+ printf '#define PROGNAME "$(NAME)"\n' >> $@
+ printf '\n' >> $@
+ printf '#endif\n' >> $@
-remembering-tests: src/remembering.c
- $(CC) $(CFLAGS) $(DEFS) $(LDFLAGS) -DTEST -o $@ $? $(LDLIBS)
+src/remembering: src/remembering.in
+$(objects) $(t-objects): src/config.h
+src/tests-lib.to: src/tests-lib.h
+src/logerr.o src/logerr.to: src/logerr.h
+src/remembering.o: src/logerr.o
+src/remembering.to: src/logerr.to src/tests-lib.to
check: all remembering-tests
./remembering-tests
+ sh tests/assert-catgets.sh $(t-sources)
+ sh tests/c-lint.sh $(t-sources)
sh tests/cli-opts.sh
sh tests/install-uninstall.sh
sh tests/ranking.sh
diff --git a/src/logerr.c b/src/logerr.c
new file mode 100644
index 0000000..029ed7f
--- /dev/null
+++ b/src/logerr.c
@@ -0,0 +1,67 @@
+#include "config.h"
+#include "logerr.h"
+
+#include <stdio.h>
+
+
+void
+logerr_file(
+ const char *const s,
+ const char *const msg,
+ const char *const file,
+ const int lineno
+) {
+ fprintf(
+ stderr,
+ "%s:%s:%d: %s: %s\n",
+ PROGNAME,
+ file,
+ lineno,
+ s,
+ msg
+ );
+}
+
+void
+logerrs_file(
+ const char *const pre,
+ const char *const mid,
+ const char *const post,
+ const char *const msg,
+ const char *const file,
+ const int lineno
+) {
+ fprintf(
+ stderr,
+ "%s:%s:%d: %s%s%s: %s\n",
+ PROGNAME,
+ file,
+ lineno,
+ pre,
+ mid,
+ post,
+ msg
+ );
+}
+
+void
+logerrl_file(
+ const char *const pre,
+ const size_t mid,
+ const char *const post,
+ const char *const msg,
+ const char *const file,
+ int lineno
+) {
+ fprintf(
+ stderr,
+ "%s:%s:%d: %s%ld%s: %s\n",
+ PROGNAME,
+ file,
+ lineno,
+ pre,
+ mid,
+ post,
+ msg
+ );
+}
diff --git a/src/logerr.h b/src/logerr.h
new file mode 100644
index 0000000..47228ab
--- /dev/null
+++ b/src/logerr.h
@@ -0,0 +1,34 @@
+#ifndef GISTATIC_LOGERR_H
+#define GISTATIC_LOGERR_H
+
+#include <stddef.h>
+
+void
+logerr_file(
+ const char *const s,
+ const char *const msg,
+ const char *const file,
+ const int lineno
+);
+
+void
+logerrs_file(
+ const char *const pre,
+ const char *const mid,
+ const char *const post,
+ const char *const msg,
+ const char *const file,
+ const int lineno
+);
+
+void
+logerrl_file(
+ const char *const pre,
+ const size_t mid,
+ const char *const post,
+ const char *const msg,
+ const char *const file,
+ const int lineno
+);
+
+#endif
diff --git a/src/remembering.c b/src/remembering.c
index 108d246..b35f798 100644
--- a/src/remembering.c
+++ b/src/remembering.c
@@ -1,6 +1,4 @@
-#ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 200809L
-#endif
+#include "config.h"
#include <stdlib.h>
#include <stdio.h>
@@ -12,6 +10,7 @@
#ifdef TEST
#include "unit-test.h"
+#include "tests-lib.h"
#include <stdbool.h>
#include <errno.h>
#endif
diff --git a/src/tests-lib.c b/src/tests-lib.c
new file mode 100644
index 0000000..a9d229a
--- /dev/null
+++ b/src/tests-lib.c
@@ -0,0 +1,29 @@
+#include "config.h"
+#include "tests-lib.h"
+#include <stdio.h>
+#include <assert.h>
+
+#define COLOUR_RESET "\033[0m"
+#define COLOUR_GREEN "\033[0;32m"
+#define COLOUR_YELLOW "\033[0;33m"
+
+void
+test_start(const char *const name) {
+ assert(fprintf(stderr, "%s():\n", name) > 0);
+}
+
+void
+testing(const char *const message) {
+ assert(
+ fprintf(
+ stderr,
+ COLOUR_YELLOW "testing" COLOUR_RESET ": %s...",
+ message
+ ) > 0
+ );
+}
+
+void
+test_ok(void) {
+ assert(fprintf(stderr, " " COLOUR_GREEN "OK" COLOUR_RESET ".\n") > 0);
+}
diff --git a/src/tests-lib.h b/src/tests-lib.h
new file mode 100644
index 0000000..1ceab27
--- /dev/null
+++ b/src/tests-lib.h
@@ -0,0 +1,13 @@
+#ifndef GISTATIC_TESTS_LIB_H
+#define GISTATIC_TESTS_LIB_H
+
+void
+test_start(const char *const name);
+
+void
+testing(const char *const message);
+
+void
+test_ok(void);
+
+#endif
diff --git a/src/unit-test.h b/src/unit-test.h
index 02922f7..2188f9f 100644
--- a/src/unit-test.h
+++ b/src/unit-test.h
@@ -8,14 +8,6 @@
#define COLOUR_GREEN "\033[0;32m"
#define COLOUR_YELLOW "\033[0;33m"
-void testing(const char *const message) {
- fprintf(stderr, COLOUR_YELLOW "testing" COLOUR_RESET ": %s...", message);
-}
-
-void test_ok() {
- fprintf(stderr, " " COLOUR_GREEN "OK" COLOUR_RESET ".\n");
-}
-
#define ASSERT_MSG "\n" COLOUR_RED "ERROR" COLOUR_RESET ": "
#define assertf(A, M, ...) if (!(A)) { fprintf(stderr, (ASSERT_MSG M "\n"), __VA_ARGS__); assert(A); }
#define asserte(A) if (!(A)) { fprintf(stderr, ASSERT_MSG "\n"); assert(A); }
diff --git a/tests/assert-catgets.sh b/tests/assert-catgets.sh
index e69de29..885e186 100644..100755
--- a/tests/assert-catgets.sh
+++ b/tests/assert-catgets.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+set -eu
+
+assert_sequential_ids() {
+ awk '
+ BEGIN {
+ n = 0
+ }
+
+ /^#define MSG_/ {
+ if (++n != $3) {
+ print "Bad sequential ID:"
+ printf "%s:%s:%s\n", FILENAME, NR, $0
+ printf "expected: %s\ngot: %s\n", n, $3
+ exit 1
+ }
+ }
+ ' "$1"
+}
+
+assert_consistent_msg_definitions() {
+ awk '
+ BEGIN {
+ i = 0
+ j = 0
+ }
+
+ /^#define MSG_/ {
+ defines[i++] = $2
+ }
+
+ /^\t\[MSG_/ {
+ msgs[j++] = substr($0, 3, index($0, "]") - 3)
+ }
+
+ END {
+ for (n in defines) {
+ if (defines[n] != msgs[n]) {
+ printf "Order mismatch between #define"
+ printf " and usage in MSGS[]:\n"
+ printf "#define: %s\nMSGS[]: %s\n",
+ defines[n], msgs[n]
+ exit 1
+ }
+ }
+ }
+ ' "$1"
+}
+
+assert_no_unused_msgs() {
+ DEFINES="$(mktemp)"
+ USAGES="$(mktemp)"
+ awk '/^#define MSG_/ { print $2 }' "$f" | sort > "$DEFINES"
+ awk -F'_\\(' '
+ /_\(MSG_/ { print substr($2, 0, index($2, ")") - 1) }
+ ' "$f" | sort | uniq > "$USAGES"
+ if ! diff "$DEFINES" "$USAGES"; then
+ echo 'Some defined MSG_ items not being used' >&2
+ exit 1
+ fi
+}
+
+for f in "$@"; do
+ assert_sequential_ids "$f"
+ assert_consistent_msg_definitions "$f"
+ assert_no_unused_msgs "$f"
+done
diff --git a/tests/c-lint.sh b/tests/c-lint.sh
index e69de29..0fa0b01 100644..100755
--- a/tests/c-lint.sh
+++ b/tests/c-lint.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+set -eu
+
+awk '
+BEGIN {
+ ret = 0
+ msg = "function not on the start of the line:"
+}
+
+/^[a-zA-Z0-9_]+ .+\(/ {
+ if (ret == 0) {
+ print msg
+ }
+ printf "%s:%s:%s\n", FILENAME, FNR, $0
+ ret = 1
+}
+
+END {
+ exit ret
+}
+' "$@"
+
+
+awk '
+BEGIN {
+ ret = 0
+ static = 1
+ msg = "non-static function is not declared in a header:"
+}
+
+/^[a-zA-Z0-9_]+\(.*$/ && static == 0 {
+ split($0, line, /\(/)
+ fn_name = line[1]
+ if (fn_name != "main") {
+ header = substr(FILENAME, 0, length(FILENAME) - 2) ".h"
+ if (system("grep -q ^\"" fn_name "\" \"" header "\"")) {
+ if (ret == 0) {
+ print msg
+ }
+ printf "%s:%s:%s\n", FILENAME, FNR, $0
+ ret = 1
+ }
+ }
+}
+
+/^static / {
+ static = 1
+}
+
+!/^static / {
+ static = 0
+}
+
+END {
+ exit ret
+}
+' "$@"
+
+
+RE='[a-z]+\(\) {'
+if grep -Eq "$RE" "$@"; then
+ echo 'Functions with no argument without explicit "void" parameter:' >&2
+ grep -En "$RE" "$@"
+ exit 1
+fi