commit 2c48bfe41adf024728335c6b844621ea936042e0 Author: Bob Polis Date: Mon Mar 16 12:05:52 2020 +0100 first commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..46d1ed8 --- /dev/null +++ b/Makefile @@ -0,0 +1,80 @@ +LIBNAME := $(shell basename $$(pwd)) +MAJOR := 1 +MINOR := 0.0 + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) + LINKERNAME := $(LIBNAME).dylib + SONAME := $(LIBNAME).$(MAJOR).dylib + REALNAME := $(LINKERNAME) +else + LINKERNAME := $(LIBNAME).so + SONAME := $(LINKERNAME).$(MAJOR) + REALNAME := $(SONAME).$(MINOR) +endif + +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +LIBDIR ?= $(PREFIX)/lib +INCLUDEDIR ?= $(PREFIX)/include +DATADIR ?= $(PREFIX)/share +MANDIR ?= $(DATADIR)/man + +SRCS := $(wildcard *.cpp) +OBJS := $(subst .cpp,.o,$(SRCS)) +DEPS := $(subst .cpp,.d,$(SRCS)) +HDRS := $(filter-out $(LIBNAME).hpp,$(wildcard *.hpp)) + +CXX ?= g++ + +CXXFLAGS := $(CXXFLAGS) -Wshadow -Wall -Wpedantic -Wextra -g -fno-strict-aliasing -std=c++17 -fPIC +ifeq ($(DEBUG),1) + CXXFLAGS += -D DEBUG -O0 +else + CXXFLAGS += -D NDEBUG -O3 +endif + +LDLIBS := + +RM := /bin/rm -f +INSTALL := /usr/bin/install -c + +all: $(REALNAME) + +$(REALNAME): $(OBJS) $(DEPS) +ifeq ($(UNAME_S),Darwin) + $(CXX) -dynamiclib -o $(REALNAME) -current_version $(MAJOR) -compatibility_version $(MINOR) $(LDFLAGS) $(LDLIBS) $(OBJS) +else + $(CXX) -g -shared -Wl,-soname,$(SONAME) -o $(REALNAME) $(LDFLAGS) $(LDLIBS) $(OBJS) +endif + +%.o: %.cpp %.d Makefile + $(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $*.d -c $< + +-include *.d + +%.d: ; + +$(LIBNAME).hpp: $(HDRS) + @echo updating $(LIBNAME).hpp + @cp /dev/null $(LIBNAME).hpp + @for h in $(HDRS); \ + do \ + cat $$h >> $(LIBNAME).hpp; \ + done + +.PHONY: clean install + +clean: + $(RM) $(OBJS) $(DEPS) $(REALNAME) $(LIBNAME).hpp + +install: $(REALNAME) $(LIBNAME).hpp + $(INSTALL) -m 644 $(REALNAME) $(LIBDIR) + $(INSTALL) -m 644 $(LIBNAME).hpp $(INCLUDEDIR) +ifeq ($(UNAME_S),Darwin) + cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME) +else + ldconfig + cd $(LIBDIR) && ln -sf $(SONAME) $(LINKERNAME) +endif diff --git a/throw.cpp b/throw.cpp new file mode 100644 index 0000000..451e81d --- /dev/null +++ b/throw.cpp @@ -0,0 +1,53 @@ +// throw macros for OS X and other POSIX systems +// adapted for Windows as well, november 2014 +// copyright © 2002-2014 Bob Polis + +#include +#include +#include +#include +#include +#include "throw.hpp" + +using namespace std; + +static string combine_message_elements(const char* file, unsigned int line, const char* user_message, const char* sys_message) +{ + ostringstream msg; + string f {file}; + msg << sys_message << " (" << f.substr(f.rfind('/') + 1) << ":" << line << ")"; + if (user_message) { + msg << ", " << user_message; + } + return msg.str(); +} + +void __throw_if_min1(int x, const char* file, unsigned int line, const char* message) +{ + if (x == -1) { + error_code ec {errno, system_category()}; + ostringstream ec_str; + ec_str << "system error " << ec.value() << ": " << ec.message(); + string msg {combine_message_elements(file, line, message, ec_str.str().c_str())}; + throw system_error {ec, msg}; + } +} + +void __throw_if_null(const void* p, const char* file, unsigned int line, const char* message) +{ + if (p == nullptr) { + string msg {combine_message_elements(file, line, message, "null pointer exception")}; + throw runtime_error {msg}; + } +} + +void __throw_if_err(int err, const char* file, unsigned int line, const char* message) +{ + if (err != 0) { + error_code ec {err, system_category()}; + ostringstream ec_str; + ec_str << "error " << err; + string msg {combine_message_elements(file, line, message, ec_str.str().c_str())}; + throw system_error {ec, msg}; + } +} diff --git a/throw.hpp b/throw.hpp new file mode 100644 index 0000000..06802b6 --- /dev/null +++ b/throw.hpp @@ -0,0 +1,21 @@ +// throw macros for OS X and other POSIX systems +// adapted for Windows as well, november 2014 +// copyright © 2002-2014 Bob Polis + +#ifndef __throw__ +#define __throw__ + +// don't call these yourself; use the macros below instead +void __throw_if_min1(int x, const char* file, unsigned int line, const char* message = nullptr); +void __throw_if_null(const void* p, const char* file, unsigned int line, const char* message = nullptr); +void __throw_if_err(int err, const char* file, unsigned int line, const char* message = nullptr); + +#define throw_if_min1(___x___) __throw_if_min1((___x___), __FILE__, __LINE__) +#define throw_if_null(__ptr__) __throw_if_null((__ptr__), __FILE__, __LINE__) +#define throw_if_err(__err__) __throw_if_err((__err__), __FILE__, __LINE__) + +#define throw_if_min1_msg(___x___, ___msg___) __throw_if_min1((___x___), __FILE__, __LINE__, ___msg___) +#define throw_if_null_msg(__ptr__, ___msg___) __throw_if_null((__ptr__), __FILE__, __LINE__, ___msg___) +#define throw_if_err_msg(__err__, ___msg___) __throw_if_err((__err__), __FILE__, __LINE__, ___msg___) + +#endif /* defined(__throw__) */