git subrepo commit libmisc
subrepo: subdir: "libmisc" merged: "ad02b40" upstream: origin: "https://git.sr.ht/~nytpu/libmisc" branch: "master" commit: "815ed88" git-subrepo: version: "0.4.3" origin: "???" commit: "???"
This commit is contained in:
parent
759532b78a
commit
43e82b425a
|
@ -38,15 +38,11 @@ PROGNAME = libmisc
|
|||
CC = cc
|
||||
AR = ar
|
||||
|
||||
## default compilation flags
|
||||
CFLAGS = -Wall -Wextra -pedantic -Wfatal-errors -std=c99 -O3 -I. \
|
||||
-Wno-missing-field-initializers -Wno-unused-parameter -Werror=return-type
|
||||
|
||||
CFLAGS =
|
||||
|
||||
## files & dependencies
|
||||
LIBS = $(PROGNAME).a
|
||||
OBJS = arena.o err.o string_util.o
|
||||
TESTS = arena.t string_util.t
|
||||
OBJS = arena.o string_util.o
|
||||
|
||||
include config.mk
|
||||
|
||||
|
@ -57,7 +53,6 @@ all: $(LIBS)
|
|||
|
||||
## dependencies
|
||||
arena.o: arena.h
|
||||
err.o: err.h
|
||||
string_util.o: string_util.h
|
||||
$(OBJS): config.mk Makefile
|
||||
|
||||
|
@ -76,33 +71,6 @@ $(PROGNAME).a: $(OBJS)
|
|||
## phonies
|
||||
# technically .PHONY isn't POSIX, but targets with a leading period aren't
|
||||
# reserved so it's still valid, it'd just be useless to actually execute
|
||||
.PHONY: all clean scan test-includes
|
||||
.PHONY: all clean
|
||||
clean:
|
||||
rm -rf $(OBJS) $(LIBS) $(TESTS)
|
||||
|
||||
# requires clang's scan-build
|
||||
# https://clang-analyzer.llvm.org/
|
||||
scan:
|
||||
printf 'Cleaning build directory and re-running make with scan-build'
|
||||
make clean
|
||||
scan-build make
|
||||
|
||||
# requires include-what-you-use
|
||||
# https://github.com/include-what-you-use/include-what-you-use
|
||||
test-includes:
|
||||
find . -type f \( -name "*.c" -o -name "*.h" \) -not -path './.ccls-cache/*'\
|
||||
-exec include-what-you-use -Xiwyu --quoted_includes_first ${CFLAGS} {} \;
|
||||
|
||||
|
||||
## testing
|
||||
$(TESTS): testing.h
|
||||
|
||||
.PHONY: test
|
||||
.SUFFIXES: .t .c
|
||||
.c.t:
|
||||
printf 'Compiling test\t$<\n'
|
||||
$(CC) $(CFLAGS) -DTEST $(LDFLAGS) -o $@ $<
|
||||
|
||||
test: $(TESTS)
|
||||
printf 'Running tests:\n'
|
||||
set -e; $(TESTS:%=./%;)
|
||||
|
|
191
libmisc/err.c
191
libmisc/err.c
|
@ -1,191 +0,0 @@
|
|||
// VERSION: 1.0.2
|
||||
/* This file contains functions similar to *BSD's err and warn family of
|
||||
* functions, but implemented portably. Also includes the {get,set}progname
|
||||
* extensions to stdlib.h.
|
||||
* See <https://www.freebsd.org/cgi/man.cgi?query=err&sektion=3> for more
|
||||
* information on these functions.
|
||||
* It should be noted that the eval parameter was removed from the err family
|
||||
* of functions, and they all exit with EXIT_FAILURE for portablilty reasons.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2021 nytpu <alex [at] nytpu.com>
|
||||
* SPDX-License-Identifier: BSL-1.0
|
||||
* The orginal source for this file is available at <https://git.sr.ht/~nytpu/libmisc>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "err.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *progname = "call setprogname()";
|
||||
static FILE *err_file;
|
||||
static void (*err_exit_func)(void);
|
||||
|
||||
const char *
|
||||
getprogname(void)
|
||||
{
|
||||
return progname;
|
||||
}
|
||||
|
||||
void
|
||||
setprogname(const char *name)
|
||||
{
|
||||
const char *p = strrchr(name, '/');
|
||||
if (p != NULL) progname = p + 1;
|
||||
else progname = name;
|
||||
}
|
||||
|
||||
void
|
||||
err_set_file(void *file)
|
||||
{
|
||||
if (file) err_file = file;
|
||||
else err_file = stderr;
|
||||
}
|
||||
|
||||
void
|
||||
err_set_exit(void (*exit_func)(void))
|
||||
{
|
||||
err_exit_func = exit_func;
|
||||
}
|
||||
|
||||
void
|
||||
err(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrc(errno, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
errc(int code, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrc(code, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
verr(const char *fmt, va_list ap)
|
||||
{
|
||||
verrc(errno, fmt, ap);
|
||||
}
|
||||
|
||||
void
|
||||
verrc(int code, const char *fmt, va_list ap)
|
||||
{
|
||||
if (err_file == NULL) err_set_file(NULL);
|
||||
fprintf(err_file, "%s: ", getprogname());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
fprintf(err_file, ": ");
|
||||
}
|
||||
fprintf(err_file, "%s\n", strerror(code));
|
||||
if (err_exit_func) err_exit_func();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnc(errno, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
warnc(int code, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnc(code, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarn(const char *fmt, va_list ap)
|
||||
{
|
||||
vwarnc(errno, fmt, ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarnc(int code, const char *fmt, va_list ap)
|
||||
{
|
||||
if (err_file == NULL) err_set_file(NULL);
|
||||
fprintf(err_file, "%s: ", getprogname());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
fprintf(err_file, ": ");
|
||||
}
|
||||
fprintf(err_file, "%s\n", strerror(code));
|
||||
}
|
||||
|
||||
void
|
||||
errx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
verrx(const char *fmt, va_list ap)
|
||||
{
|
||||
if (err_file == NULL) err_set_file(NULL);
|
||||
fprintf(err_file, "%s: ", getprogname());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
}
|
||||
fprintf(err_file, "\n");
|
||||
if (err_exit_func) err_exit_func();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void
|
||||
warnx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarnx(const char *fmt, va_list ap)
|
||||
{
|
||||
if (err_file == NULL) err_set_file(NULL);
|
||||
fprintf(err_file, "%s: ", getprogname());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
}
|
||||
fprintf(err_file, "\n");
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
// VERSION: 1.0.2
|
||||
/* This file contains functions similar to *BSD's err and warn family of
|
||||
* functions, but implemented portably. Also includes the {get,set}progname
|
||||
* extensions to stdlib.h.
|
||||
* See <https://www.freebsd.org/cgi/man.cgi?query=err&sektion=3> for more
|
||||
* information on these functions.
|
||||
* It should be noted that the eval parameter was removed from the err family
|
||||
* of functions, and they all exit with EXIT_FAILURE for portablilty reasons.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2021 nytpu <alex [at] nytpu.com>
|
||||
* SPDX-License-Identifier: BSL-1.0
|
||||
* The orginal source for this file is available at <https://git.sr.ht/~nytpu/libmisc>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef ERR_H
|
||||
#define ERR_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
// Return the program name.
|
||||
const char *getprogname(void);
|
||||
|
||||
// Set the program name to be returned with getprogname().
|
||||
// setprogname(argv[0]) should be called early in the main function, as
|
||||
// getprogname() is used in error reporting often. setprogname is not
|
||||
// reentrant, it should be called very very early, prior to binding signal
|
||||
// handlers.
|
||||
void setprogname(const char *name);
|
||||
|
||||
// Set the file to write errors to. It should be a pointer to an open FILE*,
|
||||
// or a NULL pointer to reset to stderr. The error file defaults to stderr if
|
||||
// err_set_file() is never called in a program. err_set_file is not reentrant.
|
||||
void err_set_file(void *file);
|
||||
|
||||
// Specify a function that can perform cleanup prior to exiting. Passing a
|
||||
// NULL pointer will reset the function to do nothing. The exit function is
|
||||
// called after all error messages are printed, so it is safe to close the file
|
||||
// here. err_set_exit is not reentrant.
|
||||
void err_set_exit(void (*exit_func)(void));
|
||||
|
||||
// Print the program name, a colon, then print fmt formatted with arguments and
|
||||
// another colon (if fmt is not NULL), then an error message obtained from
|
||||
// errno with strerror. Then call the exit function (see err_set_exit above),
|
||||
// and exit with code EXIT_FAILURE.
|
||||
// verr* variants use a pre-existing va_list rather than using varargs.
|
||||
// *errc variants use a provided code with strerror rather than using errno.
|
||||
void err(const char *fmt, ...);
|
||||
void errc(int code, const char *fmt, ...);
|
||||
void verr(const char *fmt, va_list ap);
|
||||
void verrc(int code, const char *fmt, va_list ap);
|
||||
|
||||
// Print the program name, a colon, then print fmt formatted with arguments and
|
||||
// another colon (if fmt is not NULL), then an error message obtained from
|
||||
// errno with strerror.
|
||||
// vwarn* variants use a pre-existing va_list rather than using varargs.
|
||||
// *warnc variants use a provided code with strerror rather than using errno.
|
||||
void warn(const char *fmt, ...);
|
||||
void warnc(int code, const char *fmt, ...);
|
||||
void vwarn(const char *fmt, va_list ap);
|
||||
void vwarnc(int code, const char *fmt, va_list ap);
|
||||
|
||||
// Print the program name, a colon, then print fmt formatted with arguments (if
|
||||
// fmt is not NULL). Then call the exit function (see err_set_exit above), and
|
||||
// exit with code EXIT_FAILURE.
|
||||
// verr* variants use a pre-existing va_list rather than using varargs.
|
||||
void errx(const char *fmt, ...);
|
||||
void verrx(const char *fmt, va_list ap);
|
||||
|
||||
// Print the program name, a colon, then print fmt formatted with arguments (if
|
||||
// fmt is not NULL).
|
||||
// vwarn* variants use a pre-existing va_list rather than using varargs.
|
||||
void warnx(const char *fmt, ...);
|
||||
void vwarnx(const char *fmt, va_list ap);
|
||||
|
||||
#endif // ERR_H
|
|
@ -1,117 +0,0 @@
|
|||
// VERSION: 1.0.2
|
||||
/* This is inspired by <https://text.causal.agency/005-testing-c.txt> and is
|
||||
* meant to act as a supplement to make printing messages easier for that setup
|
||||
*
|
||||
* To use, first set up your makefile as specified in the aforementioned link.
|
||||
* Add the file to be tested to the TESTS macro in the makefile to include it
|
||||
* in testing.
|
||||
*
|
||||
* Then, simply add this to the end of the file you want to test:
|
||||
* #ifdef TEST
|
||||
* #include "testing.h"
|
||||
*
|
||||
* int
|
||||
* main(void)
|
||||
* {
|
||||
* begin_tests("<FILENAME>");
|
||||
* begin_group("<GROUP>");
|
||||
* // if you just want the condition printed on assertion failure
|
||||
* assert(...);
|
||||
* // if you want a custom message printed on assertion failure
|
||||
* assert_msg(..., "message");
|
||||
* end_group();
|
||||
* end_tests();
|
||||
* }
|
||||
*
|
||||
* #endif // TEST
|
||||
*
|
||||
* Add more groups as needed.
|
||||
* It's best to assert the output of a single function (writing helper
|
||||
* functions if needed).
|
||||
*
|
||||
* Note that the test binaries aren't linked with the rest of the code, so
|
||||
* you will need to stub functions from other translation units.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2021 nytpu <alex [at] nytpu.com>
|
||||
* SPDX-License-Identifier: BSL-1.0
|
||||
* The orginal source for this file is available at <https://git.sr.ht/~nytpu/libmisc>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef TESTING_H
|
||||
#define TESTING_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const char *filename = NULL;
|
||||
static const char *groupname = NULL;
|
||||
|
||||
// equivalent to assert() but prints out a custom message rather than the
|
||||
// provided assertion
|
||||
#define assert_msg(expr, msg) \
|
||||
if (!(expr)) { \
|
||||
fprintf(stderr, "%s\n", msg); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
// {begin,end}_tests are meant to be used at a file level, but can also be used
|
||||
// to declare "supergroups" for files with lots of tests
|
||||
static inline void
|
||||
begin_tests(const char *fn)
|
||||
{
|
||||
assert_msg(filename == NULL, "You must call end_tests before beginning new tests.");
|
||||
assert_msg(fn != NULL, "Provide a filename.");
|
||||
filename = fn;
|
||||
fprintf(stderr, "---\n%s tests begin.\n", filename);
|
||||
}
|
||||
static inline void
|
||||
end_tests(void)
|
||||
{
|
||||
assert_msg(filename != NULL, "begin_tests MUST be called before end_tests");
|
||||
fprintf(stderr, "all %s tests passed.\n", filename);
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
// A testing group is meant to be a small unit of testing, and is the smallest
|
||||
// unit that will have a success message printed
|
||||
static inline void
|
||||
begin_group(const char *gn)
|
||||
{
|
||||
assert_msg(groupname == NULL, "You must call end_group before starting a new group.");
|
||||
assert_msg(gn != NULL, "Provide a group name.");
|
||||
groupname = gn;
|
||||
}
|
||||
static inline void
|
||||
end_group(void)
|
||||
{
|
||||
assert_msg(groupname != NULL, "begin_group MUST be called before end_group.");
|
||||
fprintf(stderr, "\tall %s tests passed.\n", groupname);
|
||||
groupname = NULL;
|
||||
}
|
||||
|
||||
#endif // TESTING_H
|
Loading…
Reference in New Issue