mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-13 14:59:34 +02:00
config/git: import suckless sbase
i currently use the output of sha512sum in several places of xbmk, which is a bit unreliable in case output changes. other cases where i use util outputs in variables are probably reliable, because i'm using mostly posix utilities in those. to mitigate this, i now import suckless sbase, which has a reasonable sha512sum implementation. *every* binary it builds is being placed in build.list, because i'll probably start using more of them. for example, i may start modifying the "date" implementation, adding the GNU-specific options that i need as mentioned on init.sh i'm importing it in util/ because the sha512sum util is needed for verifying project sources, so if sbase itself is a "project source", that means we can into a chicken and egg bootstrapping problem. this is sbase at revision: 055cc1ae1b3a13c3d8f25af0a4a3316590efcd48 Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "text.h"
|
||||
#include "utf.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct Range {
|
||||
size_t min, max;
|
||||
struct Range *next;
|
||||
} Range;
|
||||
|
||||
static Range *list = NULL;
|
||||
static char mode = 0;
|
||||
static char *delim = "\t";
|
||||
static size_t delimlen = 1;
|
||||
static int nflag = 0;
|
||||
static int sflag = 0;
|
||||
|
||||
static void
|
||||
insert(Range *r)
|
||||
{
|
||||
Range *l, *p, *t;
|
||||
|
||||
for (p = NULL, l = list; l; p = l, l = l->next) {
|
||||
if (r->max && r->max + 1 < l->min) {
|
||||
r->next = l;
|
||||
break;
|
||||
} else if (!l->max || r->min < l->max + 2) {
|
||||
l->min = MIN(r->min, l->min);
|
||||
for (p = l, t = l->next; t; p = t, t = t->next)
|
||||
if (r->max && r->max + 1 < t->min)
|
||||
break;
|
||||
l->max = (p->max && r->max) ? MAX(p->max, r->max) : 0;
|
||||
l->next = t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (p)
|
||||
p->next = r;
|
||||
else
|
||||
list = r;
|
||||
}
|
||||
|
||||
static void
|
||||
parselist(char *str)
|
||||
{
|
||||
char *s;
|
||||
size_t n = 1;
|
||||
Range *r;
|
||||
|
||||
if (!*str)
|
||||
eprintf("empty list\n");
|
||||
for (s = str; *s; s++) {
|
||||
if (*s == ' ')
|
||||
*s = ',';
|
||||
if (*s == ',')
|
||||
n++;
|
||||
}
|
||||
r = ereallocarray(NULL, n, sizeof(*r));
|
||||
for (s = str; n; n--, s++) {
|
||||
r->min = (*s == '-') ? 1 : strtoul(s, &s, 10);
|
||||
r->max = (*s == '-') ? strtoul(s + 1, &s, 10) : r->min;
|
||||
r->next = NULL;
|
||||
if (!r->min || (r->max && r->max < r->min) || (*s && *s != ','))
|
||||
eprintf("bad list value\n");
|
||||
insert(r++);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
seek(struct line *s, size_t pos, size_t *prev, size_t count)
|
||||
{
|
||||
size_t n = pos - *prev, i, j;
|
||||
|
||||
if (mode == 'b') {
|
||||
if (n >= s->len)
|
||||
return s->len;
|
||||
if (nflag)
|
||||
while (n && !UTF8_POINT(s->data[n]))
|
||||
n--;
|
||||
*prev += n;
|
||||
return n;
|
||||
} else if (mode == 'c') {
|
||||
for (n++, i = 0; i < s->len; i++)
|
||||
if (UTF8_POINT(s->data[i]) && !--n)
|
||||
break;
|
||||
} else {
|
||||
for (i = (count < delimlen + 1) ? 0 : delimlen; n && i < s->len; ) {
|
||||
if ((s->len - i) >= delimlen &&
|
||||
!memcmp(s->data + i, delim, delimlen)) {
|
||||
if (!--n && count)
|
||||
break;
|
||||
i += delimlen;
|
||||
continue;
|
||||
}
|
||||
for (j = 1; j + i <= s->len && !fullrune(s->data + i, j); j++);
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
*prev = pos;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
cut(FILE *fp, const char *fname)
|
||||
{
|
||||
Range *r;
|
||||
struct line s;
|
||||
static struct line line;
|
||||
static size_t size;
|
||||
size_t i, n, p;
|
||||
ssize_t len;
|
||||
|
||||
while ((len = getline(&line.data, &size, fp)) > 0) {
|
||||
line.len = len;
|
||||
if (line.data[line.len - 1] == '\n')
|
||||
line.data[--line.len] = '\0';
|
||||
if (mode == 'f' && !memmem(line.data, line.len, delim, delimlen)) {
|
||||
if (!sflag) {
|
||||
fwrite(line.data, 1, line.len, stdout);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (i = 0, p = 1, s = line, r = list; r; r = r->next) {
|
||||
n = seek(&s, r->min, &p, i);
|
||||
s.data += n;
|
||||
s.len -= n;
|
||||
i += (mode == 'f') ? delimlen : 1;
|
||||
if (!s.len)
|
||||
break;
|
||||
if (!r->max) {
|
||||
fwrite(s.data, 1, s.len, stdout);
|
||||
break;
|
||||
}
|
||||
n = seek(&s, r->max + 1, &p, i);
|
||||
i += (mode == 'f') ? delimlen : 1;
|
||||
if (fwrite(s.data, 1, n, stdout) != n)
|
||||
eprintf("fwrite <stdout>:");
|
||||
s.data += n;
|
||||
s.len -= n;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
if (ferror(fp))
|
||||
eprintf("getline %s:", fname);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
eprintf("usage: %s -b list [-n] [file ...]\n"
|
||||
" %s -c list [file ...]\n"
|
||||
" %s -f list [-d delim] [-s] [file ...]\n",
|
||||
argv0, argv0, argv0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
int ret = 0;
|
||||
|
||||
ARGBEGIN {
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'f':
|
||||
mode = ARGC();
|
||||
parselist(EARGF(usage()));
|
||||
break;
|
||||
case 'd':
|
||||
delim = EARGF(usage());
|
||||
if (!*delim)
|
||||
eprintf("empty delimiter\n");
|
||||
delimlen = unescape(delim);
|
||||
break;
|
||||
case 'n':
|
||||
nflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
} ARGEND
|
||||
|
||||
if (!mode)
|
||||
usage();
|
||||
|
||||
if (!argc)
|
||||
cut(stdin, "<stdin>");
|
||||
else {
|
||||
for (; *argv; argc--, argv++) {
|
||||
if (!strcmp(*argv, "-")) {
|
||||
*argv = "<stdin>";
|
||||
fp = stdin;
|
||||
} else if (!(fp = fopen(*argv, "r"))) {
|
||||
weprintf("fopen %s:", *argv);
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
cut(fp, *argv);
|
||||
if (fp != stdin && fshut(fp, *argv))
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user