diff options
author | Mattias Andrée <maandree@kth.se> | 2024-02-17 11:18:12 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-02-17 11:18:12 +0100 |
commit | 3303dd0cfe91f0686063066221ea55115ae3708f (patch) | |
tree | 7fac8cb98b28bcb56808b7658dc57797dc39c3b2 /check | |
parent | Add check rule (diff) | |
download | simple-icon-theme-3303dd0cfe91f0686063066221ea55115ae3708f.tar.gz simple-icon-theme-3303dd0cfe91f0686063066221ea55115ae3708f.tar.bz2 simple-icon-theme-3303dd0cfe91f0686063066221ea55115ae3708f.tar.xz |
Reimplement check/find-errors in C so nonstandard flags (-o and -r) for grep(1) are not required12
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rwxr-xr-x | check/find-errors | 4 | ||||
-rw-r--r-- | check/find-errors.c | 180 |
2 files changed, 180 insertions, 4 deletions
diff --git a/check/find-errors b/check/find-errors deleted file mode 100755 index c557a4b..0000000 --- a/check/find-errors +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -! grep -ro '#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' scalable/ \ -| tr 'A-F' 'a-f' \ -| grep -v '#\(bebebe\|ef2929\|f57900\|32a679\|cd656c\|d69553\|ccad47\|32a679\|00a09f\|2495be\|a46eb0\|32a678\)' diff --git a/check/find-errors.c b/check/find-errors.c new file mode 100644 index 0000000..021f041 --- /dev/null +++ b/check/find-errors.c @@ -0,0 +1,180 @@ +#include <sys/stat.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +static int exitstatus = 0; +static char *path = NULL; +static size_t pathsize = 0; +static size_t pathlen = 0; +static char *buf = NULL; +static size_t bufsize = 0; + + +static void +pushname(const char *name, size_t *old_len_out) +{ + size_t len = pathlen + strlen(name) + 1; + + if (pathsize < len + 1) { + pathsize = len + 1; + path = realloc(path, pathsize); + if (!path) { + perror("find-errors"); + exit(1); + } + } + + *old_len_out = pathlen; + pathlen = (size_t)(stpcpy(pathlen ? stpcpy(&path[pathlen], "/") : path, name) - path); + +} + + +static void +popname(size_t old_len) +{ + pathlen = old_len; + path[pathlen] = '\0'; +} + + +static void +checkfile(const char *name) +{ + size_t old; + int fd; + size_t len = 0; + ssize_t r; + size_t off; + size_t i; + + pushname(name, &old); + + fd = open(path, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "find-errors: open %s O_RDONLY: %s\n", path, strerror(errno)); + exit(1); + } + for (;;) { + if (len == bufsize) { + bufsize += 1024; + buf = realloc(buf, bufsize); + if (!buf) { + perror("find-errors"); + exit(1); + } + } + r = read(fd, &buf[len], bufsize - len); + if (r <= 0) { + if (!r) + break; + fprintf(stderr, "find-errors: read %s: %s\n", path, strerror(errno)); + exit(1); + } + len += (size_t)r; + } + close(fd); + + if (len < 7) + goto out; + + for (off = 0; off < len - 6; off++) { + if (buf[off] != '#') + continue; + for (i = 1; i <= 6; i++) { + if ('A' <= buf[off + i] && buf[off + i] <= 'F') + buf[off + i] ^= 'A' ^ 'a'; + else if (!(('a' <= buf[off + i] && buf[off + i] <= 'f') || + ('0' <= buf[off + i] && buf[off + i] <= '9'))) + goto next; + } + if (!strncmp(&buf[off + 1], "bebebe", 6) || + !strncmp(&buf[off + 1], "ef2929", 6) || + !strncmp(&buf[off + 1], "f57900", 6) || + !strncmp(&buf[off + 1], "32a678", 6) || + !strncmp(&buf[off + 1], "cd656c", 6) || + !strncmp(&buf[off + 1], "d69553", 6) || + !strncmp(&buf[off + 1], "ccad47", 6) || + !strncmp(&buf[off + 1], "32a679", 6) || + !strncmp(&buf[off + 1], "00a09f", 6) || + !strncmp(&buf[off + 1], "2495be", 6) || + !strncmp(&buf[off + 1], "a46eb0", 6) || + !strncmp(&buf[off + 1], "000000", 6)) + continue; + fprintf(stderr, "%s uses colour not defined in theme: %.7s\n", path, &buf[off]); + exitstatus = 1; + next:; + } + +out: + popname(old); +} + + +static void +checkdir(const char *name) +{ + size_t old; + DIR *dir; + static size_t old2; + static struct dirent *f; + static struct stat st; + + pushname(name, &old); + + dir = opendir(path); + if (!dir) { + fprintf(stderr, "find-errors: opendir %s: %s\n", path, strerror(errno)); + exit(1); + } + + errno = 0; + while ((f = readdir(dir))) { + if (f->d_name[0] == '.') + continue; + if (f->d_type == DT_DIR) { + goto dir; + } else if (f->d_type == DT_REG) { + goto reg; + } else if (f->d_type == DT_UNKNOWN) { + pushname(f->d_name, &old2); + if (lstat(path, &st)) { + fprintf(stderr, "find-errors: lstat %s: %s\n", path, strerror(errno)); + exit(1); + } + popname(old2); + if (S_ISDIR(st.st_mode)) { + dir: + checkdir(f->d_name); + } else if (S_ISREG(st.st_mode)) { + reg: + if (strlen(f->d_name) > 4 && !memcmp(&f->d_name[strlen(f->d_name) - 4], ".svg", 4)) + checkfile(f->d_name); + } + } + } + + if (errno) { + fprintf(stderr, "find-errors: readdir %s: %s\n", path, strerror(errno)); + exit(1); + } + + closedir(dir); + popname(old); +} + + +int +main(void) +{ + checkdir("scalable"); + free(path); + free(buf); + return exitstatus; +} |