Skip to content

Commit

Permalink
fix!: error values and improve coverage
Browse files Browse the repository at this point in the history
refactor: move read/write file to util
- remove unreachable if block
  • Loading branch information
mpolitzer committed Apr 29, 2024
1 parent 158948a commit a3827c3
Show file tree
Hide file tree
Showing 12 changed files with 459 additions and 377 deletions.
252 changes: 27 additions & 225 deletions sys-utils/libcmt/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,235 +14,37 @@
# See the License for the specific language governing permissions and
# limitations under the License.

LIBCMT_VERSION ?=0.0.0

INSTALL_FILE= install -m0644
INSTALL_EXEC= install -m0755

# paths
PREFIX = /usr
TARGET_PREFIX ?= $(PREFIX)

TOOLCHAIN_PREFIX ?= riscv64-linux-gnu-
TARGET_CC := $(TOOLCHAIN_PREFIX)gcc
TARGET_AR := $(TOOLCHAIN_PREFIX)ar
COMMON_CFLAGS := -Wvla -O2 -g -Wall -pedantic -Wextra -Isrc \
-fno-strict-aliasing -fno-strict-overflow
TARGET_CFLAGS := $(COMMON_CFLAGS) -ftrivial-auto-var-init=zero -Wstrict-aliasing=3
CFLAGS := $(COMMON_CFLAGS)
CC := gcc

all: libcmt host
host: mock tools
#-------------------------------------------------------------------------------
examples_SRC := \
doc/examples/abi_encode_000.c \
doc/examples/abi_encode_001.c \
doc/examples/abi_encode_002.c \
doc/examples/abi_decode_000.c \
doc/examples/abi_decode_001.c \
doc/examples/abi_decode_002.c \
doc/examples/io.c \
doc/examples/rollup.c

examples_OBJDIR := build/examples
examples_OBJ := $(patsubst %.c,$(examples_OBJDIR)/%.o,$(examples_SRC))

$(examples_OBJ): $(examples_OBJDIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $<

# no need to link, just ensure examples build correctly
examples: $(examples_OBJ)

#-------------------------------------------------------------------------------
libcmt_SRC := \
src/buf.c \
src/abi.c \
src/keccak.c \
src/merkle.c \
src/rollup.c \
src/util.c \
src/io.c

libcmt_OBJDIR := build/lib
libcmt_OBJ := $(patsubst %.c,$(libcmt_OBJDIR)/%.o,$(libcmt_SRC))
libcmt_LIB := $(libcmt_OBJDIR)/libcmt.a

$(libcmt_OBJ): $(libcmt_OBJDIR)/%.o: %.c
@mkdir -p $(@D)
$(TARGET_CC) $(TARGET_CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $<

$(libcmt_LIB): $(libcmt_OBJ)
$(TARGET_AR) rcs $@ $^

libcmt: $(libcmt_LIB)
install: $(libcmt_LIB)
mkdir -p $(TARGET_DESTDIR)$(TARGET_PREFIX)/lib
cp -f $< $(TARGET_DESTDIR)$(TARGET_PREFIX)/lib
mkdir -p $(TARGET_DESTDIR)$(TARGET_PREFIX)/include/libcmt/
cp -f src/*.h $(TARGET_DESTDIR)$(TARGET_PREFIX)/include/libcmt/
mkdir -p $(TARGET_DESTDIR)$(TARGET_PREFIX)/lib/pkgconfig
sed -e 's|@ARG_PREFIX@|$(TARGET_PREFIX)|g' src/libcmt.pc > $(TARGET_DESTDIR)$(TARGET_PREFIX)/lib/pkgconfig/libcmt.pc

debian-package: install
mkdir -p $(TARGET_DESTDIR)/DEBIAN
sed 's|ARG_VERSION|$(LIBCMT_VERSION)|g;' tools/template/cross-control.template > $(TARGET_DESTDIR)/DEBIAN/control
dpkg-deb -Zxz --root-owner-group --build $(TARGET_DESTDIR) $(LIBCMT_DEB_FILENAME)

#-------------------------------------------------------------------------------
mock_SRC := \
src/abi.c \
src/buf.c \
src/keccak.c \
src/merkle.c \
src/rollup.c \
src/util.c \
src/io-mock.c

mock_OBJDIR := build/mock
mock_OBJ := $(patsubst %.c,$(mock_OBJDIR)/%.o,$(mock_SRC))
mock_LIB := $(mock_OBJDIR)/libcmt.a

$(mock_OBJ): $(mock_OBJDIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d) -c -o $@ $<

$(mock_LIB): $(mock_OBJ)
$(AR) rcs $@ $^

mock: $(mock_LIB)

install-mock: $(mock_LIB)
mkdir -p $(DESTDIR)$(PREFIX)/lib
cp -f $< $(DESTDIR)$(PREFIX)/lib
cp -f src/*.h $(DESTDIR)$(PREFIX)/include/libcmt/
mkdir -p $(DESTDIR)$(PREFIX)/lib/pkgconfig
sed -e 's|@ARG_PREFIX@|$(PREFIX)|g' src/libcmt_mock.pc > $(DESTDIR)$(PREFIX)/lib/pkgconfig/libcmt.pc

#-------------------------------------------------------------------------------
unittests_BINS := \
$(mock_OBJDIR)/abi-multi \
$(mock_OBJDIR)/abi-single \
$(mock_OBJDIR)/buf \
$(mock_OBJDIR)/gio \
$(mock_OBJDIR)/keccak \
$(mock_OBJDIR)/merkle \
$(mock_OBJDIR)/progress \
$(mock_OBJDIR)/rollup

$(mock_OBJDIR)/abi-multi: tests/abi-multi.c $(mock_LIB)
$(CC) $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/abi-single: tests/abi-single.c $(mock_LIB)
$(CC) $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/buf: tests/buf.c $(mock_LIB)
$(CC) $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/keccak: tests/keccak.c $(mock_LIB)
$(CC) $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/merkle: tests/merkle.c $(mock_LIB)
$(CC) $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/gio: tests/gio.c tests/data.h $(mock_LIB)
$(CC) -Itests $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/rollup: tests/rollup.c tests/data.h $(mock_LIB)
$(CC) -Itests $(CFLAGS) -o $@ $^

$(mock_OBJDIR)/progress: tests/progress.c $(mock_LIB)
$(CC) -Itests $(CFLAGS) -o $@ $^

test: $(unittests_BINS)
$(foreach test,$(unittests_BINS),$(test) &&) true

tests/data.h: tests/create-data.sh
$< > $@

#-------------------------------------------------------------------------------
tools_OBJDIR := build/tools
tools_BINS := \
$(tools_OBJDIR)/funsel

$(tools_OBJDIR)/funsel: tools/funsel.c $(mock_LIB)
@mkdir -p $(@D)
$(CC) $(CFLAGS) -o $@ $^

tools: $(tools_BINS)

#-------------------------------------------------------------------------------
LINTER_IGNORE_SOURCES=src/io.c
LINTER_IGNORE_HEADERS=
LINTER_SOURCES=$(filter-out $(LINTER_IGNORE_SOURCES),$(strip $(wildcard src/*.c) $(wildcard tests/*.c) $(wildcard tools/*.c)))
LINTER_HEADERS=$(filter-out $(LINTER_IGNORE_HEADERS),$(strip $(wildcard src/*.h)))

CLANG_TIDY=clang-tidy
CLANG_TIDY_TARGETS=$(patsubst %.c,%.clang-tidy,$(LINTER_SOURCES))

CLANG_FORMAT=clang-format
CLANG_FORMAT_FILES:=$(wildcard src/*.c) $(wildcard src/*.h) $(wildcard tests/*.c) $(wildcard tools/*.c)
CLANG_FORMAT_IGNORE_FILES:=
CLANG_FORMAT_FILES:=$(strip $(CLANG_FORMAT_FILES))
CLANG_FORMAT_FILES:=$(filter-out $(CLANG_FORMAT_IGNORE_FILES),$(strip $(CLANG_FORMAT_FILES)))

EMPTY:=
SPACE:=$(EMPTY) $(EMPTY)
CLANG_TIDY_HEADER_FILTER=$(CURDIR)/($(subst $(SPACE),|,$(LINTER_HEADERS)))

%.clang-tidy: %.c
@$(CLANG_TIDY) --header-filter='$(CLANG_TIDY_HEADER_FILTER)' $< -- $(CFLAGS) 2>/dev/null
@$(CC) $(CFLAGS) $< -MM -MT $@ -MF $@.d > /dev/null 2>&1
@touch $@

clangd-config:
@echo "$(CFLAGS)" | sed -e $$'s/ \{1,\}/\\\n/g' | grep -v "MMD" > compile_flags.txt

format:
@$(CLANG_FORMAT) -i $(CLANG_FORMAT_FILES)

check-format:
@$(CLANG_FORMAT) -Werror --dry-run $(CLANG_FORMAT_FILES)

lint: $(CLANG_TIDY_TARGETS)

#-------------------------------------------------------------------------------

help:
@echo "Targets: (default: '*')"
@echo "* all - Build libcmt and host targets"
@echo " host - Build mock and tools targets"
@echo " libcmt - Build the library, tools and examples; to run on the cartesi-machine."
@echo " (requires the cartesi Linux headers to build)"
@echo " mock - Build a mocked version of the library, tools and examples; to run on the host system."
@echo " tools - Build tools on top of the mocked library to run on the host system."
@echo " test - Build and run tests on top of the mocked library on the host system."
@echo " doc - Build the documentation and API references as html."
@echo " clean - remove the binaries and objects."
@echo " install - Install the library and C headers; on the host system."
@echo " Use TARGET_DESTDIR and TARGET_PREFIX to customize the installation."
@echo " install-mock - Install the mocked version of the library and C headers; on the host system."
@echo " Use DESTDIR and PREFIX to customize the installation."
O=build

DESTDIR ?= _install
PREFIX ?= /usr

export DESTDIR
export PREFIX

all: $O
@ninja --quiet -C $O #&> /dev/null

$O $O/build.ninja:
meson setup \
-Dprefix=$(PREFIX) \
-Dc_std=gnu2x \
-Dwarning_level=3 \
-Db_coverage=true \
--cross-file=riscv64.ini \
$O #&> /dev/null

cov: coverage-html
coverage-html: test
test: all
install uninstall test coverage-html: $O
@ninja --quiet -C $O $@
clean:
rm -rf $O

doc/theme:
git clone git@github.com:jothepro/doxygen-awesome-css.git $@
git -C doc/theme checkout 8cea9a073ecd50a5b2c0958a3df100292d6c7374

doc: doc/theme examples
doxygen doc/Doxyfile

clean:
@rm -rf build
@rm -rf src/*.clang-tidy src/*.d
@rm -rf tests/*.clang-tidy tests/*.d
@rm -rf tools/*.clang-tidy tools/*.d
@rm -rf *.bin

distclean: clean
@rm -rf doc/html doc/theme
@rm -rf compile_flags.txt

OBJ := $(mock_OBJ) $(libcmt_OBJ) $(examples_OBJ) $(tools_OBJ)

-include $(OBJ:%.o=%.d)
8 changes: 4 additions & 4 deletions sys-utils/libcmt/src/abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ int cmt_abi_put_funsel(cmt_buf_t *me, uint32_t funsel) {

int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]) {
if (n > CMT_WORD_LENGTH) {
return EDOM;
return -EDOM;
}
for (size_t i = 0; i < n; ++i) {
out[CMT_WORD_LENGTH - 1 - i] = data[i];
Expand All @@ -52,7 +52,7 @@ int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_L

int cmt_abi_encode_uint_nn(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]) {
if (n > CMT_WORD_LENGTH) {
return EDOM;
return -EDOM;
}
for (size_t i = 0; i < CMT_WORD_LENGTH - n; ++i) {
out[i] = 0;
Expand All @@ -73,7 +73,7 @@ int cmt_abi_encode_uint(size_t n, const void *data, uint8_t out[CMT_WORD_LENGTH]

int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) {
if (n > CMT_WORD_LENGTH) {
return EDOM;
return -EDOM;
}
for (size_t i = 0; i < CMT_WORD_LENGTH - n; ++i) {
if (data[i]) {
Expand All @@ -88,7 +88,7 @@ int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_

int cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) {
if (n > CMT_WORD_LENGTH) {
return EDOM;
return -EDOM;
}
for (size_t i = 0; i < CMT_WORD_LENGTH - n; ++i) {
if (data[i]) {
Expand Down
46 changes: 3 additions & 43 deletions sys-utils/libcmt/src/io-mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
/** track the number of open "devices". Mimic the kernel driver behavior by limiting it to 1 */
static int open_count = 0;

static int read_whole_file(const char *name, size_t max, void *data, size_t *length);
static int write_whole_file(const char *name, size_t length, const void *data);

int cmt_io_init(cmt_io_driver_t *_me) {
if (!_me) {
return -EINVAL;
Expand Down Expand Up @@ -116,7 +113,7 @@ static int load_next_input(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) {
}

size_t file_length = 0;
int rc = read_whole_file(filepath, cmt_buf_length(me->rx), me->rx->begin, &file_length);
int rc = cmt_util_read_whole_file(filepath, cmt_buf_length(me->rx), me->rx->begin, &file_length);
if (rc) {
if (cmt_util_debug_enabled()) {
(void) fprintf(stderr, "failed to load \"%s\". %s\n", filepath, strerror(-rc));
Expand Down Expand Up @@ -150,7 +147,7 @@ static int store_output(cmt_io_driver_mock_t *me, const char *filepath, struct c
return -ENOBUFS;
}

int rc = write_whole_file(filepath, rr->data, me->tx->begin);
int rc = cmt_util_write_whole_file(filepath, rr->data, me->tx->begin);
if (rc) {
(void) fprintf(stderr, "failed to store \"%s\". %s\n", filepath, strerror(-rc));
return rc;
Expand Down Expand Up @@ -205,7 +202,7 @@ static int mock_rx_rejected(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) {
}
(void) fprintf(stderr, "%s:%d no revert for the mock implementation\n", __FILE__, __LINE__);
if (load_next_input(me, rr)) {
return -1;
return -ENOSYS;
}
return 0;
}
Expand Down Expand Up @@ -255,9 +252,6 @@ static int mock_tx_gio(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) {

/* These behaviours are defined by the cartesi-machine emulator */
static int cmt_io_yield_inner(cmt_io_driver_t *_me, struct cmt_io_yield *rr) {
if (!_me) {
return -EINVAL;
}
cmt_io_driver_mock_t *me = &_me->mock;

if (rr->cmd == HTIF_YIELD_CMD_MANUAL) {
Expand Down Expand Up @@ -327,37 +321,3 @@ int cmt_io_yield(cmt_io_driver_t *_me, struct cmt_io_yield *rr) {
return rc;
}

static int read_whole_file(const char *name, size_t max, void *data, size_t *length) {
int rc = 0;

FILE *file = fopen(name, "rb");
if (!file) {
return -errno;
}

*length = fread(data, 1, max, file);
if (!feof(file)) {
rc = -ENOBUFS;
}
if (fclose(file) != 0) {
rc = -errno;
}
return rc;
}

static int write_whole_file(const char *name, size_t length, const void *data) {
int rc = 0;

FILE *file = fopen(name, "wb");
if (!file) {
return -errno;
}

if (fwrite(data, 1, length, file) != length) {
rc = -EIO;
}
if (fclose(file) != 0) {
rc = -errno;
}
return rc;
}

0 comments on commit a3827c3

Please sign in to comment.