libstr-c

C string library
git clone https://git.sinitax.com/sinitax/libstr-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit aeee626d4d6a7b3cbb4d5ae4b1698331d2da8227
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun, 30 Apr 2023 23:25:26 +0200

Add basic string allocation api

Diffstat:
A.gitignore | 3+++
A.gitmodules | 3+++
AMakefile | 38++++++++++++++++++++++++++++++++++++++
Ainclude/str.h | 9+++++++++
Alib/liballoc | 1+
Alibstr.api | 3+++
Alibstr.lds | 7+++++++
Asrc/str.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +.cache +build +compile_commands.json diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/liballoc"] + path = lib/liballoc + url = git@sinitax.com:snx/liballoc diff --git a/Makefile b/Makefile @@ -0,0 +1,38 @@ +PREFIX ?= /usr/local +LIBDIR ?= /lib +INCLDIR ?= /include + +CFLAGS = -Wconversion -Wunused-function -Wunused-variable +CFLAGS += -I lib/liballoc/include -I include + +all: build/libstr.a build/libstr.so + +clean: + rm -rf build + +build: + mkdir build + +lib/liballoc/build/liballoc.a: + make -C lib/liballoc build/liballoc.a + +build/libstr.a: src/str.c include/str.h libstr.api lib/liballoc/build/liballoc.a | build + $(CC) -o build/tmp.o src/str.c $(CFLAGS) -r + objcopy --keep-global-symbols=libstr.api build/tmp.o build/fixed.o + ar rcs $@ build/fixed.o + +build/libstr.so: src/str.c include/str.h libstr.lds | build + $(CC) -o $@ src/str.c $(CFLAGS) \ + -shared -Wl,-version-script libstr.lds + +install: + install -m755 build/libstr.a -t "$(DESTDIR)$(PREFIX)$(LIBDIR)" + install -m755 build/libstr.so -t "$(DESTDIR)$(PREFIX)$(LIBDIR)" + install -m644 include/str.h -t "$(DESTDIR)$(PREFIX)$(INCLDIR)" + +uninstall: + rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/libstr.a" + rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/libstr.so" + rm -f "$(DESTDIR)$(PREFIX)$(INCLDIR)/str.h" + +.PHONY: all clean install uninstall diff --git a/include/str.h b/include/str.h @@ -0,0 +1,9 @@ +#pragma once + +#include "allocator.h" + +#include <stdarg.h> + +int str_fmt(struct allocator *allocator, char **out, const char *fmstr, ...); +int str_dup(struct allocator *allocator, char **out, const char *str); +int str_app(struct allocator *allocator, char **out, const char *app); diff --git a/lib/liballoc b/lib/liballoc @@ -0,0 +1 @@ +Subproject commit 5b667362498ed4cdc6ad5a9036834c6ab1bed4e9 diff --git a/libstr.api b/libstr.api @@ -0,0 +1,3 @@ +str_fmt +str_dup +str_app diff --git a/libstr.lds b/libstr.lds @@ -0,0 +1,7 @@ +LIBSTR_1.0 { + global: + str_fmt; + str_dup; + str_app; + local: *; +}; diff --git a/src/str.c b/src/str.c @@ -0,0 +1,60 @@ +#include "str.h" + +#include <string.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +int +str_fmt(struct allocator *allocator, char **out, const char *fmtstr, ...) +{ + va_list ap, cpy; + ssize_t n; + int rc; + + va_copy(cpy, ap); + + va_start(cpy, fmtstr); + n = vsnprintf(NULL, 0, fmtstr, cpy); + va_end(cpy); + if (n <= 0) return 1; + + rc = allocator->alloc((void **) out, (size_t) (n + 1)); + if (rc) return -rc; + + va_start(ap, fmtstr); + vsnprintf(*out, (size_t) (n + 1), fmtstr, ap); + va_end(ap); + + return 0; +} + +int +str_dup(struct allocator *allocator, char **out, const char *str) +{ + int rc; + + rc = allocator->alloc((void **) out, strlen(str) + 1); + if (rc) return -1; + + strcpy(*out, str); + + return 0; +} + +int +str_app(struct allocator *allocator, char **str, const char *app) +{ + size_t slen, alen; + int rc; + + alen = strlen(app); + slen = *str ? strlen(*str) : 0; + + rc = allocator->realloc((void **) str, slen + alen + 1); + if (rc) return -rc; + + memcpy(*str + slen, app, alen + 1); + + return 0; +}