author | Olivier Brunel
<jjk@jjacky.com> 2023-02-28 09:20:39 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-02-28 15:26:31 UTC |
parent | 9318e9bca2ef6755b6d9c9da4de0c3e4999ef89a |
doc/sacoloff.3.md | +43 | -0 |
doc/sacolptr.3.md | +88 | -0 |
doc/saoff2ptr.3.md | +29 | -0 |
include/limb/samisc.h | +10 | -0 |
meta/libs/limb | +4 | -0 |
src/sacoloff.c | +21 | -0 |
src/sacolptr.c | +15 | -0 |
src/saoff2ptr.c | +13 | -0 |
diff --git a/doc/sacoloff.3.md b/doc/sacoloff.3.md new file mode 100644 index 0000000..e3fba94 --- /dev/null +++ b/doc/sacoloff.3.md @@ -0,0 +1,43 @@ +% limb manual +% sacoloff(3) + +# NAME + +sacoloff - append an array of offsets to strings from an stralloc into it + +# SYNOPSIS + + #include <limb/samisc.h> + +```pre hl +int sacoloff(stralloc *<em>sa</em>, size_t <em>from</em>, size_t <em>end</em>) +``` + +# DESCRIPTION + +The `sacoloff`() function will scan the content of the given stralloc `sa` +starting at offset `from`, expecting to find a succession of NUL-terminated +strings, up to `end`. It will append into `sa` an array of offsets where each +string is located within `sa->s`. + +! INFO: +! The offsets added into `sa` are actually casted as *uintptr_t* so that they +! can later be turned into full string pointers (*char \**) if needed. +! Such a conversion can be done using [saoff2ptr](3). + +# RETURN VALUE + +Upon successful completion, the `sacoloff`() function returns the number of +strings found, or the number of elements in the array. Otherwise, it returns -1 +and sets `errno` to indicate the error. + +# ERRORS + +The `sacoloff`() function may fail if : + +: *ENOMEM* +:: Out of memory to add pointers into `sa` + +# SEE ALSO + +[saoff2ptr](3), [sacolptr](3) diff --git a/doc/sacolptr.3.md b/doc/sacolptr.3.md new file mode 100644 index 0000000..c373aed --- /dev/null +++ b/doc/sacolptr.3.md @@ -0,0 +1,88 @@ +% limb manual +% sacolptr(3) + +# NAME + +sacolptr - append an array of pointers to strings from an stralloc into it + +# SYNOPSIS + + #include <limb/samisc.h> + +```pre hl +int sacolptr(stralloc *<em>sa</em>, size_t <em>from</em>, size_t <em>end</em>) +``` + +# DESCRIPTION + +The `sacolptr`() function will scan the content of the given stralloc `sa` +starting at offset `from`, expecting to find a succession of NUL-terminated +strings, up to `end`. It will append into `sa` an array of pointers to the +strings. + +This allows to use said array easily with other functions not stralloc-aware. + +! INFO: +! This function is merely is wrapper around [sacoloff](3) and [saoff2ptr](3). + +# RETURN VALUE + +Upon successful completion, the `sacolptr`() function returns the number of +strings found, or the number of elements in the array. Otherwise, it returns -1 +and sets `errno` to indicate the error. + +# ERRORS + +The `sacolptr`() function may fail and set `errno` for any of the errors +specified on [sacoloff](3). + +# EXAMPLE + +To get the list of files in the current directory, and sort them using +[qsort](3), one could do the following (Note the lack of error checking) : + +```c +#include <stdlib.h> +#include <string.h> +#include <skalibs/stralloc.h> +#include <limb/output.h> +#include <limb/samisc.h> + +static int +cmp(const void *p1, const void *p2) +{ + const char *s1 = * (const char **) p1; + const char *s2 = * (const char **) p2; + return strcmp(s1, s2); +} + +int +main(void) +{ + stralloc sa = STRALLOC_ZERO; + + /* append the list of all files in the current directory into sa */ + salst(&sa, ".", NULL); + + /* offset where the array will be stored */ + size_t arroff = sa.len; + + /* append the array from strings contained within */ + int n = sacolptr(&sa, 0, sa.len); + + /* sort the array */ + char **arr = (char **) (sa.s + arroff); + qsort(arr, n, sizeof(char *), cmp); + + /* show ordered listing */ + for (int i = 0; i < n; ++i, ++arr) + out(*arr); + + stralloc_free(&sa); + return 0; +} +``` + +# SEE ALSO + +[sacoloff](3), [saoff2ptr](3) diff --git a/doc/saoff2ptr.3.md b/doc/saoff2ptr.3.md new file mode 100644 index 0000000..3f3a2a4 --- /dev/null +++ b/doc/saoff2ptr.3.md @@ -0,0 +1,29 @@ +% limb manual +% saoff2ptr(3) + +# NAME + +saoff2ptr - turn an array of offsets from an stralloc into an array of strings + +# SYNOPSIS + + #include <limb/samisc.h> + +```pre hl +void saoff2ptr(stralloc *<em>sa</em>, size_t <em>arroff</em>, size_t <em>n</em>) +``` + +# DESCRIPTION + +The `saoff2ptr`() function will transform an array of `n` offsets located at +`arroff` into `sa->s` into an array of string pointers. + +This allows to use said array easily with other functions not stralloc-aware. + +! HINT: +! You can easily append such an array of offsets from a concatenation of +! NUL-terminated strings into a stralloc using [sacoloff](3). + +# SEE ALSO + +[sacoloff](3), [sacolptr](3) diff --git a/include/limb/samisc.h b/include/limb/samisc.h new file mode 100644 index 0000000..0c32b25 --- /dev/null +++ b/include/limb/samisc.h @@ -0,0 +1,10 @@ +#ifndef LIMB_SAMISC_H +#define LIMB_SAMISC_H + +#include <skalibs/stralloc.h> + +extern int sacoloff(stralloc *sa, size_t from, size_t end); +extern void saoff2ptr(stralloc *sa, size_t arroff, size_t n); +extern int sacolptr(stralloc *sa, size_t from, size_t end); + +#endif /* LIMB_SAMISC_H */ diff --git a/meta/libs/limb b/meta/libs/limb index 76c5560..6a447d2 100644 --- a/meta/libs/limb +++ b/meta/libs/limb @@ -16,6 +16,10 @@ obj/rmstar_in_tmpat.o obj/rmstar_tmpat.o obj/salsat.o obj/sareadlinkat.o +# samisc.h +obj/sacoloff.o +obj/saoff2ptr.o +obj/sacolptr.o # buffer.h obj/buffer_putescall.o obj/buffer_putesc.o diff --git a/src/sacoloff.c b/src/sacoloff.c new file mode 100644 index 0000000..25ea28e --- /dev/null +++ b/src/sacoloff.c @@ -0,0 +1,21 @@ +#include <stdint.h> /* uintptr_t */ +#include "limb/samisc.h" + +int +sacoloff(stralloc *sa, size_t from, size_t end) +{ + size_t salen = sa->len; + int ret = 0; + + for (uintptr_t off = from; off < end; ) { + if (!stralloc_catb(sa, (char *) &off, sizeof(off))) { + sa->len = salen; + return -1; + } + + off += strlen(sa->s + off) + 1; + ++ret; + } + + return ret; +} diff --git a/src/sacolptr.c b/src/sacolptr.c new file mode 100644 index 0000000..4193581 --- /dev/null +++ b/src/sacolptr.c @@ -0,0 +1,15 @@ +#include "limb/samisc.h" + +int +sacolptr(stralloc *sa, size_t from, size_t end) +{ + size_t arroff = sa->len; + /* first collect the offsets from sa->s, as relocation might happen as we + * grow sa to store the array */ + int n = sacoloff(sa, from, end); + if (n < 0) + return n; + /* then turn offsets into pointers */ + saoff2ptr(sa, arroff, n); + return n; +} diff --git a/src/saoff2ptr.c b/src/saoff2ptr.c new file mode 100644 index 0000000..08e1546 --- /dev/null +++ b/src/saoff2ptr.c @@ -0,0 +1,13 @@ +#include <stdint.h> /* uintptr_t */ +#include "limb/samisc.h" + +void +saoff2ptr(stralloc *sa, size_t arroff, size_t n) +{ + uintptr_t *a = (uintptr_t *) (sa->s + arroff); + for (int i = 0; i < n; ++i) { + /* add the base, and turn this into a proper pointer */ + *a += (uintptr_t) sa->s; + ++a; + } +}