// Copyright © Tavian Barnes <tavianator@tavianator.com>
// SPDX-License-Identifier: 0BSD
#include "color.h"
#include "alloc.h"
#include "bfstd.h"
#include "bftw.h"
#include "config.h"
#include "diag.h"
#include "dir.h"
#include "dstring.h"
#include "expr.h"
#include "fsade.h"
#include "stat.h"
#include "trie.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
struct colors {
char *reset;
char *leftcode;
char *rightcode;
char *endcode;
char *clear_to_eol;
char *bold;
char *gray;
char *red;
char *green;
char *yellow;
char *blue;
char *magenta;
char *cyan;
char *white;
char *warning;
char *error;
char *normal;
char *file;
char *multi_hard;
char *executable;
char *capable;
char *setgid;
char *setuid;
char *directory;
char *sticky;
char *other_writable;
char *sticky_other_writable;
char *link;
char *orphan;
char *missing;
bool link_as_target;
char *blockdev;
char *chardev;
char *door;
char *pipe;
char *socket;
/** A mapping from color names (fi, di, ln, etc.) to struct fields. */
struct trie names;
/** A mapping from file extensions to colors. */
struct trie ext_colors;
};
/** Initialize a color in the table. */
static int init_color(struct colors *colors, const char *name, const char *value, char **field) {
if (value) {
*field = dstrdup(value);
if (!*field) {
return -1;
}
} else {
*field = NULL;
}
struct trie_leaf *leaf = trie_insert_str(&colors->names, name);
if (leaf) {
leaf->value = field;
return 0;
} else {
return -1;
}
}
/** Get a color from the table. */
static char **get_color(const struct colors *colors, const char *name) {
const struct trie_leaf *leaf = trie_find_str(&colors->names, name);
if (leaf) {
return (char **)leaf->value;
} else {
return NULL;
}
}
/** Set the value of a color. */
static int set_color(struct colors *colors, const char *name, char *value) {
char **color = get_color(colors, name);
if (color) {
dstrfree(*color);
*color = value;
return 0;
} else {
return -1;
}
}
/**
* Transform a file extension for fast lookups, by reversing and lowercasing it.
*/
static void extxfrm(char *ext, size_t len) {
for (size_t i = 0; i < len - i; ++i)