Compare commits

...

4 Commits

Author SHA1 Message Date
951a3a45ad Migrate to latest project structure
Bumped version to 1.0.1
2025-01-08 13:30:07 +01:00
45b5ba897b Move test scripts into test-scripts 2025-01-08 13:29:40 +01:00
3a857e8980 Add visual note 2024-12-19 09:13:40 +01:00
46c4a1ac97 Fix links in README 2024-11-26 14:47:10 +01:00
25 changed files with 485 additions and 55 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
*.inc
curly curly

304
Makefile
View File

@ -1,27 +1,40 @@
include premake.make include premake.make
BIN := $(shell basename $$(pwd)) # git commit hash and version for this build
COMMIT-HASH != git log 2>/dev/null | sed -e '1s/^commit //;q'
COMMIT := "static const char* commit = \"$(COMMIT-HASH)\";"
VERSION := "static const char* version = \"$(MAJOR).$(MINOR).$(PATCH)\";"
MANSECTION ?= 1 # some important install locations
MANPAGE := $(BIN).$(MANSECTION)
SRCS := $(notdir $(wildcard src/*.cpp))
OBJS := $(SRCS:.cpp=.o)
DEPS := $(SRCS:.cpp=.d)
BUILDDIR := build/intermediates/
PREFIX ?= /usr/local PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/man/man
CONFIGDIR ?= $(PREFIX)/etc CONFIGDIR ?= $(PREFIX)/etc
DATADIR ?= $(PREFIX)/share INCLUDEDIR ?= $(PREFIX)/include
DOCDIR ?= $(DATADIR)/$(BIN)/doc LIBDIR ?= $(PREFIX)/lib
MANDIR ?= $(PREFIX)/man
DATADIR ?= $(PREFIX)/share/$(PROJ)
DOCDIR ?= $(DATADIR)/doc
# setup naming and versioning for library product
ifeq ($(UNAME_S), Darwin)
LINKERNAME := $(PROJ).dylib
SONAME := $(PROJ).$(MAJOR).dylib
REALNAME := $(LINKERNAME)
else ifeq ($(UNAME_S), OpenBSD)
REALNAME := $(PROJ).so.$(MAJOR).$(MINOR)
else ifeq ($(UNAME_S), Linux)
LINKERNAME := $(PROJ).so
SONAME := $(LINKERNAME).$(MAJOR)
REALNAME := $(SONAME).$(MINOR).$(PATCH)
endif
STATICLIB := $(PROJ).a
# select default compiler
CXX ?= g++ CXX ?= g++
RM := /bin/rm -rf
INSTALL := /usr/bin/install -c
CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -g -std=c++17 # setup compiler flags and build config
CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -Wno-unused-parameter
CXXFLAGS += -g3 -fPIC
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
CXXFLAGS += -DDEBUG -O0 CXXFLAGS += -DDEBUG -O0
CONFIG := debug CONFIG := debug
@ -29,42 +42,253 @@ else
CXXFLAGS += -DNDEBUG -O3 CXXFLAGS += -DNDEBUG -O3
CONFIG := release CONFIG := release
endif endif
OUTDIR := build/$(CONFIG)/
vpath %.cpp src # setup build locations
vpath %.d $(BUILDDIR) OUTDIR := build/$(CONFIG)
vpath %.o $(BUILDDIR) BUILDDIR := build/obj
BIN := $(OUTDIR)/$(PROJ)
.PHONY: all clean install prebuild test dist-clean # define sources and derived files
# allow for extra sources defined in premake.make
SRCS += $(notdir $(wildcard src/*.cpp))
OBJS := $(addprefix $(BUILDDIR)/, $(SRCS:.cpp=.o))
DEPS := $(addprefix $(BUILDDIR)/, $(SRCS:.cpp=.dep))
HDRS ?= $(filter-out src/precomp.hpp, $(wildcard src/*.hpp))
MANS := $(addprefix $(PREFIX)/, $(wildcard man/man*/*))
all: prebuild $(OUTDIR)$(BIN) # if project supports plugins, link to libdl where needed
ifdef PLUGINS
ifeq ($(UNAME_S),Darwin)
LDLIBS += -ldl
else ifeq ($(UNAME_S),Linux)
LDLIBS += -ldl
endif
endif
prebuild: # pattern rules ===========================================================
@mkdir -p $(BUILDDIR) $(OUTDIR)
$(OUTDIR)$(BIN): $(OBJS) $(BUILDDIR)/%.o: src/%.cpp
$(CXX) -o $(OUTDIR)$(BIN) $(LDFLAGS) $(addprefix $(BUILDDIR),$(OBJS)) $(LDLIBS) ifeq ($(PRECOMPILE), 1)
@ln -sf $(OUTDIR)$(BIN) $(BIN) $(CXX) $(CXXFLAGS) -o $@ -include precomp.hpp -MMD -MP -MT $@ -MF $(BUILDDIR)/$*.dep -c $<
else
$(CXX) $(CXXFLAGS) -o $@ -MMD -MP -MT $@ -MF $(BUILDDIR)/$*.dep -c $<
endif
%.o %.d: %.cpp %.dep: ;
$(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $*.d -c $<
@mv $@ $*.d $(BUILDDIR)
-include $(addprefix $(BUILDDIR), $(DEPS)) $(MANDIR)/man1/%: man/man1/%
install -m 0644 $< $@
$(MANDIR)/man3/%: man/man3/%
install -m 0644 $< $@
$(MANDIR)/man5/%: man/man5/%
install -m 0644 $< $@
# =========================================================== pattern rules
# targets =================================================================
.PHONY: all commit-hash version plugins test clean dist-clean install-plugins \
install install-data uninstall-data uninstall-plugins uninstall
# main target
ifeq ($(PRODUCT), tool)
all: $(BUILDDIR) $(OUTDIR) commit-hash version plugins $(BIN)
else ifeq ($(PRODUCT), lib)
all: $(BUILDDIR) $(OUTDIR) commit-hash version plugins $(OUTDIR)/$(REALNAME) $(OUTDIR)/$(STATICLIB)
endif
$(BUILDDIR):
mkdir -p $@
$(OUTDIR):
mkdir -p $@
# product build rules
ifeq ($(PRODUCT), tool) # -------------------------------------------- tool
ifeq ($(PRECOMPILE), 1)
$(BIN): precomp.hpp.gch $(OBJS)
else
$(BIN): $(OBJS)
endif
$(CXX) -o $(BIN) $(LDFLAGS) $(OBJS) $(LDLIBS)
@ln -sf $(BIN) $(PROJ)
endif # -------------------------------------------------------------- tool
ifeq ($(PRODUCT), lib) # ---------------------------------------------- lib
ifeq ($(PRECOMPILE), 1)
$(OUTDIR)/$(REALNAME): precomp.hpp.gch $(OBJS)
else
$(OUTDIR)/$(REALNAME): $(OBJS)
endif
ifeq ($(UNAME_S),Darwin)
$(CXX) -dynamiclib -o $(OUTDIR)/$(REALNAME) -install_name $(LIBDIR)/$(REALNAME) \
-current_version $(MAJOR) -compatibility_version $(MINOR) $(LDFLAGS) $(OBJS) $(LDLIBS)
else ifeq ($(UNAME_S),OpenBSD)
$(CXX) -g -shared -Wl,-soname,$(REALNAME) -o $(OUTDIR)/$(REALNAME) $(LDFLAGS) $(OBJS) $(LDLIBS)
else ifeq ($(UNAME_S),Linux)
$(CXX) -g -shared -Wl,-soname,$(SONAME) -o $(OUTDIR)/$(REALNAME) $(LDFLAGS) $(OBJS) $(LDLIBS)
endif
$(OUTDIR)/$(STATICLIB): $(OBJS)
ar r $(OUTDIR)/$(STATICLIB) $(OBJS)
ifeq ($(GENERATELIBHEADER),1)
$(OUTDIR)/$(PROJ).hpp: $(HDRS)
@echo updating $(OUTDIR)/$(PROJ).hpp
@cp /dev/null $(OUTDIR)/$(PROJ).hpp
@for h in $(HDRS); \
do \
sed '/@exclude/d' $$h >> $(OUTDIR)/$(PROJ).hpp; \
done
endif
endif # --------------------------------------------------------------- lib
# get generated dependencies, if any
-include $(DEPS)
commit-hash:
@if ! echo $(COMMIT) | diff -q src/commit.inc - >/dev/null 2>&1 ;\
then \
echo $(COMMIT) > src/commit.inc ;\
fi
version:
@if ! echo $(VERSION) | diff -q src/version.inc - >/dev/null 2>&1 ;\
then \
echo $(VERSION) > src/version.inc ;\
fi
$(BUILDDIR)/version.o: src/version.inc src/commit.inc
precomp.hpp.gch: src/precomp.hpp
$(CXX) $< $(CXXFLAGS) -o $@
plugins:
ifdef PLUGINS
@for plug in $(PLUGINS) ;\
do \
$(MAKE) -C $$plug ;\
done
endif
test: test:
$(MAKE) -C tests && tests/tests $(MAKE) -C tests && tests/tests
clean: clean:
$(RM) $(BUILDDIR) rm -rf $(BUILDDIR) tests/build tests/tests tests/src/commit.inc tests/src/version.inc
$(MAKE) -C tests clean ifdef PLUGINS
@for plug in $(PLUGINS) ;\
do \
$(MAKE) -C $$plug clean ;\
done
endif
dist-clean: dist-clean: clean
$(RM) build $(BIN) rm -rf build $(PROJ) src/commit.inc src/version.inc precomp.hpp.gch
$(MAKE) -C tests clean
install: $(MANDIR)/man1:
$(INSTALL) -d $(BINDIR) install -m 0755 -d $@
$(INSTALL) $(OUTDIR)$(BIN) $(BINDIR)
$(INSTALL) -d $(MANDIR)$(MANSECTION) $(MANDIR)/man3:
$(INSTALL) -m 0644 $(MANPAGE) $(MANDIR)$(MANSECTION) install -m 0755 -d $@
$(MANDIR)/man5:
install -m 0755 -d $@
$(DATADIR):
install -m 0755 -d $@
# (un)install targets
ifdef DATAFILES
install-data: $(DATADIR)
install -m 0644 $(DATAFILES) $(DATADIR)
else
install-data:
endif
uninstall-data:
rm -rf $(DATADIR)
install-plugins:
ifdef PLUGINS
@for plug in $(PLUGINS) ;\
do \
$(MAKE) -C $$plug install ;\
done
endif
uninstall-plugins:
ifdef PLUGINS
@for plug in $(PLUGINS) ;\
do \
$(MAKE) -C $$plug uninstall ;\
done
endif
ifeq ($(PRODUCT), tool) # -------------------------------------------- tool
$(BINDIR):
install -m 0755 -d $@
install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(BINDIR) $(MANS) install-data install-plugins
install -m 0755 $(BIN) $(BINDIR)
uninstall: uninstall-data uninstall-plugins
rm -f $(BINDIR)/$(PROJ) $(MANS)
endif # -------------------------------------------------------------- tool
ifeq ($(PRODUCT), lib) # ---------------------------------------------- lib
$(LIBDIR):
install -m 0755 -d $@
$(INCLUDEDIR):
install -m 0755 -d $@
$(INCLUDEDIR)/$(PROJ):
install -m 0755 -d $@
ifeq ($(GENERATELIBHEADER), 1)
install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(OUTDIR)/$(PROJ).hpp install-data install-plugins
install -m 0644 $(OUTDIR)/$(PROJ).hpp $(INCLUDEDIR)
else
install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(INCLUDEDIR)/$(PROJ) install-data install-plugins
install -m 0644 $(HDRS) $(INCLUDEDIR)/$(PROJ)
endif
install -m 0644 $(OUTDIR)/$(REALNAME) $(LIBDIR)
install -m 0644 $(OUTDIR)/$(STATICLIB) $(LIBDIR)
ifeq ($(UNAME_S), Darwin)
cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME)
else ifeq ($(UNAME_S), Linux)
ifeq ($(USER), root)
ldconfig
else
cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME)
endif
cd $(LIBDIR) && ln -sf $(SONAME) $(LINKERNAME)
else ifeq ($(UNAME_S), OpenBSD)
ldconfig -R
endif
uninstall: uninstall-data uninstall-plugins
rm -rf $(INCLUDEDIR)/$(PROJ).hpp $(INCLUDEDIR)/$(PROJ) $(MANS) $(LIBDIR)/$(STATICLIB) $(LIBDIR)/$(REALNAME) $(LIBDIR)/$(SONAME) $(LIBDIR)/$(LINKERNAME)
ifeq ($(UNAME_S), Linux)
ldconfig
else ifeq ($(UNAME_S), OpenBSD)
ldconfig -R
endif
endif # --------------------------------------------------------------- lib
# ================================================================= targets
# project-specific targets go in here
-include postmake.make

View File

@ -1,11 +1,14 @@
# curly — Working solution to the Krul puzzle # curly — Working solution to the Krul puzzle
This tool will run a small compiler which implements the language from the (Krul This tool will run a small compiler which implements the language from the [Krul
puzzle)[https://bobpolis.com/krul/]. The sources also contain an older puzzle](https://bobpolis.com/krul/). The sources also contain an older
implementation, to be found in the interpreter files. This could also be used as implementation, to be found in the interpreter files. This could also be used as
a drop-in replacement for the compiler, by changing the appropriate line in a drop-in replacement for the compiler, by changing the appropriate line in
`main.cpp`. `main.cpp`.
> [!Note]
> Running `curly` without arguments, it will show the solution to the online puzzle. When run with file arguments, it will try to parse those files as Krul sources and run them.
## Building ## Building
Build using: Build using:
@ -14,9 +17,9 @@ Build using:
but first install the dependencies: but first install the dependencies:
- (libsclogging)[https://git.bobpolis.com/bob/libsclogging] - [libsclogging](https://git.bobpolis.com/bob/libsclogging)
- (libscterm)[https://git.bobpolis.com/bob/libscterm] - [libscterm](https://git.bobpolis.com/bob/libscterm)
- (libscrequest)[https://git.bobpolis.com/bob/libscrequest] - [libscrequest](https://git.bobpolis.com/bob/libscrequest)
- libcurl - libcurl
## Install ## Install

View File

@ -1 +1,31 @@
LDLIBS := -lm -lpthread -lcurl -lsclogging -lscterm -lscrequest # Define linker flags here, like: -lsqlite3 -lpthread
LDLIBS := -lcurl -lsclogging -lscterm -lscrequest
# Dir name becomes product name.
PROJ := $(shell basename $$(pwd))
# Find out what platform we're on, e.g. Darwin, Linux, OpenBSD.
UNAME_S := $(shell uname -s)
# We will build a tool, not a library.
PRODUCT := tool
# Single source of truth for version.
MAJOR := 1
MINOR := 0
PATCH := 1
# Specify desired C++ standard for this project.
CXXFLAGS += -std=c++20
# Set to 1 if you want a precompiled header for the C++ Standard Library.
PRECOMPILE := 0
# List of extra files to be installed in DATADIR (/usr/local/share/$(PROJ) by default)
DATAFILES :=
# Define plugin sub-projects here. Assumption here is a directory "plugins"
# containing plugin sub-projects, each in its own directory.
# Rename and/or repeat accordingly.
PLUGINS := $(wildcard plugins/*)
MAKE += --no-print-directory

View File

@ -8,19 +8,16 @@
#include <libsclogging.hpp> #include <libsclogging.hpp>
#include <libscrequest.hpp> #include <libscrequest.hpp>
#include "compiler.hpp" #include "compiler.hpp"
#include "version.hpp"
sc::logger logger {"curly", sc::loglevel::info}; sc::logger logger {"curly", sc::loglevel::info};
void print_help() { static void print_help() {
std::cout << "usage: curly [-h|--version]\n"; std::cout << "usage: curly [-h|--version]\n";
std::cout << " -h, --help show this help text and exit\n"; std::cout << " -h, --help show this help text and exit\n";
std::cout << " --version show version number and exit\n"; std::cout << " --version show version number and exit\n";
} }
void print_version() {
std::cout << "curly version 1.0\n";
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
try { try {
int opt_char, opt_val; int opt_char, opt_val;
@ -36,7 +33,7 @@ int main(int argc, char* argv[]) {
// handle long-only options here // handle long-only options here
switch (opt_val) { switch (opt_val) {
case 1: case 1:
print_version(); std::cout << curly_version() << '\n';
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
break; break;

127
src/precomp.hpp Normal file
View File

@ -0,0 +1,127 @@
// C++98 (first official C++ standard)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if (__cplusplus >= 201103L) // C++11
#include <array>
#include <atomic>
#include <cfenv>
#include <chrono>
#include <cinttypes>
#include <codecvt> // deprecated in C++17, removed in C++26
#include <condition_variable>
#include <cstdint>
#include <cuchar>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>
#endif // C++11
#if (__cplusplus >= 201402L) // C++14
#include <shared_mutex>
#endif // C++14
#if (__cplusplus >= 201703L) // C++17
#include <any>
#include <charconv>
#include <execution>
#include <filesystem>
#include <memory_resource>
#include <optional>
#include <string_view>
#include <variant>
#endif // C++17
#if (__cplusplus >= 202002L) // C++20
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#include <coroutine>
#include <format>
#include <latch>
#include <numbers>
#include <ranges>
#include <semaphore>
#include <source_location>
#include <span>
//#include <stop_token> not yet supported by clang 16
//#include <syncstream> not yet supported by clang 17
#include <version>
#endif // C++20
#if (__cplusplus >= 202302L) // C++23
#include <expected>
#include <flat_map>
#include <flat_set>
#include <generator>
#include <mdspan>
#include <print>
#include <spanstream>
#include <stacktrace>
#include <stdfloat>
#endif // C++23
#if (__cplusplus > 202302L) // C++26
#include <debugging>
#include <hazard_pointer>
#include <inplace_vector>
#include <linalg>
#include <rcu>
#include <text_encoding>
#endif // C++26

19
src/version.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "version.hpp"
#include <sstream>
std::string curly_version() {
#include "version.inc"
#include "commit.inc"
std::ostringstream oss;
oss << "curly version " << version;
#ifdef DEBUG
oss << " DEBUG";
#endif
oss << '\n';
if (commit[0] != '\0') {
oss << "build " << commit << ", ";
}
oss << __DATE__ << ", " << __TIME__ << '\n';
oss << "(c) Bob Polis, all rights reserved";
return oss.str();
}

8
src/version.hpp Normal file
View File

@ -0,0 +1,8 @@
#ifndef _CURLY_VERSION_H_
#define _CURLY_VERSION_H_
#include <string>
std::string curly_version();
#endif // _CURLY_VERSION_H_

1
tests/Makefile Symbolic link
View File

@ -0,0 +1 @@
../Makefile

6
tests/postmake.make Normal file
View File

@ -0,0 +1,6 @@
$(BUILDDIR)/%.o: ../src/%.cpp
ifeq ($(PRECOMPILE), 1)
$(CXX) $(CXXFLAGS) -o $@ -include precomp.hpp -MMD -MP -MT $@ -MF $(BUILDDIR)/$*.dep -c $<
else
$(CXX) $(CXXFLAGS) -o $@ -MMD -MP -MT $@ -MF $(BUILDDIR)/$*.dep -c $<
endif

5
tests/premake.make Normal file
View File

@ -0,0 +1,5 @@
include ../premake.make
LDLIBS += -lboost_unit_test_framework
CXXFLAGS += -I../src
SRCS := $(notdir $(filter-out ../src/main.cpp,$(wildcard ../src/*.cpp)))
PRODUCT := tool

8
tests/src/main.cpp Normal file
View File

@ -0,0 +1,8 @@
#define BOOST_TEST_MODULE My Test
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(first_test)
{
BOOST_TEST(1 == 1);
}

1
tests/src/precomp.hpp Symbolic link
View File

@ -0,0 +1 @@
../../src/precomp.hpp