From bba67091ac18bfcf886dc1221dea218aa119618e Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 30 May 2021 15:59:03 -0400 Subject: Revamp to improve everything, and support D30547 https://reviews.freebsd.org/D30547 --- common.c | 65 +++++++++++++++++++++++++-------------------------------- common.h | 13 +++++++----- dirconvert.1 | 1 - dirconvert.c | 35 +++++++++++++++++++++++++++---- opendircolors.c | 36 +++++++++++++++++++++----------- 5 files changed, 92 insertions(+), 58 deletions(-) diff --git a/common.c b/common.c index afbb27e..bbabfc9 100644 --- a/common.c +++ b/common.c @@ -30,48 +30,41 @@ #include #include #include +#include #include "common.h" -char -numtocol(char c, bool bold) +struct color * +parseansi(char *ansi, struct color *color) { - char buf = col[strtol(&c, NULL, 10)]; - if (bold) - return (toupper(buf)); - else - return (buf); -} + long long num; + char *token; + const char *errstr; + bool bold = false, underline = false; -char * -tolscolors(char *dircolor) -{ - char *ent, *buf, *val, *val2; - char out[22] = "xxxxxxxxxxxxxxxxxxxxxx"; - bool bold = false; + color->fg = 'x'; + color->bg = 'x'; - while ((ent = buf = strsep(&dircolor, ":")) != NULL) { - for (int i = 0; i < 11; i++) { - if (strncmp(ent, types[i], strlen(types[i])) == 0) { - bold = false; - while ((val = strsep(&buf, "=")) != NULL) { - while ((val2 = strsep(&val, ";")) != - NULL) { - if (strcmp(val2, "01") == 0) { - bold = true; - } else if (val2[0] == '3') { - out[2 * i] = numtocol( - val2[1], bold); - } else if (val2[0] == '4') { - out[2 * i + 1] = - numtocol( - val2[1], NULL); - } - } - } - } + while ((token = strsep(&ansi, ";")) != NULL) { + num = strtonum(token, 0, 47, NULL); + switch (num) { + case 1: + bold = true; + break; + case 4: + underline = true; + break; + default: + if (num <= 37) + color->fg = (char)((num - 30) + 97); + else if (num <= 47) + color->bg = (char)((num - 40) + 97); } } - char *ret = strdup(out); - return (ret); + if (bold) + color->fg = toupper(color->fg); + if (underline) + color->bg = toupper(color->bg); + + return color; } diff --git a/common.h b/common.h index b82776b..fa181d8 100644 --- a/common.h +++ b/common.h @@ -30,10 +30,13 @@ #define COMMON_H #include -static const char *types[11] = { "di", "ln", "so", "pi", "ex", "bd", "cd", "su", - "sg", "tw", "ow" }; -static const char col[8] = "abcdefgh"; -char *tolscolors(char *); -char numtocol(char, bool); +#define MAXKEYLEN 21 + +struct color { + char fg; + char bg; +}; + +struct color *parseansi(char *, struct color*); #endif diff --git a/dirconvert.1 b/dirconvert.1 index c92cc32..267a472 100644 --- a/dirconvert.1 +++ b/dirconvert.1 @@ -40,7 +40,6 @@ If the input is a single dash .Pq Sq Fl .Nm reads the first line from the standard input. -.El .Sh EXIT STATUS .Ex -std .Sh EXAMPLE diff --git a/dirconvert.c b/dirconvert.c index 41982c1..b2bf6e6 100644 --- a/dirconvert.c +++ b/dirconvert.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -35,8 +36,12 @@ #include "common.h" +static const char *types[11] = { "di", "ln", "so", "pi", "ex", "bd", "cd", "su", + "sg", "tw", "ow" }; + void usage(const char *); char *tols_colors(char *); +char *tolscolors(char *); int main(int argc, char **argv) @@ -75,14 +80,14 @@ tols_colors(char *lscolors) sprintf(ls_out + strlen(ls_out), "%s=", types[i]); if (isupper(lscolors[2 * i])) sprintf(ls_out + strlen(ls_out), "01;"); + if (isupper(lscolors[2 * i + 1])) + sprintf(ls_out + strlen(ls_out), "04;"); if (tolower(lscolors[2 * i]) == 'x') sprintf(ls_out + strlen(ls_out), "00"); else if (tolower(lscolors[2 * i] != 'x')) - sprintf(ls_out + strlen(ls_out), "3%i", - (int)(strchr(col, tolower(lscolors[2 * i])) - col)); + sprintf(ls_out + strlen(ls_out), "3%i", (int)tolower(lscolors[2 * i]) - 97); if (tolower(lscolors[2 * i + 1]) != 'x') - sprintf(ls_out + strlen(ls_out), ";4%i", - (int)(strchr(col, tolower(lscolors[2 * i])) - col)); + sprintf(ls_out + strlen(ls_out), ";4%i", (int)tolower(lscolors[2 * i + 1]) - 97); sprintf(ls_out + strlen(ls_out), ":"); } char *ret = strdup(ls_out); @@ -90,6 +95,28 @@ tols_colors(char *lscolors) return (ret); } +char * +tolscolors(char *dircolor) +{ + char *ent; + char key[2] = "", val[MAXKEYLEN] = ""; + char out[22] = "xxxxxxxxxxxxxxxxxxxx"; + struct color color; + + while ((ent = strsep(&dircolor, ":")) != NULL) { + for (int i = 0; i < 11; i++) { + if (strncmp(ent, types[i], strlen(types[i])) == 0) { + sscanf(ent, "%c%c=%s", &key[0], &key[1], val); + parseansi(val, &color); + out[2 * i] = color.fg; + out[2 * i + 1] = color.bg; + } + } + } + char *ret = strdup(out); + return (ret); +} + void usage(const char *progname) { diff --git a/opendircolors.c b/opendircolors.c index 21855ba..9be81f6 100644 --- a/opendircolors.c +++ b/opendircolors.c @@ -26,10 +26,12 @@ * SUCH DAMAGE. */ +#include #include #include #include #include +#include #include #include #include @@ -37,9 +39,7 @@ #include "common.h" -void usage(const char *); - -#define MAXKEYLEN 21 +static void usage(const char *); static const struct option long_options[] = { /* no clang-format */ { "help", no_argument, NULL, 'h' }, /**/ @@ -62,6 +62,11 @@ static const char *short_types[38] = { "no", "no", "fi", "rs", "di", "ln", "ln", "lc", "lc", "rc", "rc", "ec", "ec", "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", "mh", "cl", NULL }; +static const int indexes[37] = { -1, -1, -1, -1, 0, 1, 1, + 1, -1, -1, 3, 3, 2, 5, 5, 6, 6, -1, 4, + -1, -1, -1, -1, -1, -1, 7, 7, 8, 8, -1, 10, + 10, 9, 9, -1, -1, -1 }; + int main(int argc, char **argv) { @@ -110,39 +115,46 @@ main(int argc, char **argv) char *line = NULL; size_t linecap = 0; ssize_t linelen; - char *out = strdup(""); + char *ls_out = strdup(""); + char lsout[22] = "xxxxxxxxxxxxxxxxxxxxxx"; + struct color color; + while ((linelen = getline(&line, &linecap, fd)) > 0) { if (*line == '#' || *line == '\n') continue; char fmttype[MAXKEYLEN] = "", val[MAXKEYLEN] = ""; sscanf(line, "%s %s\n", fmttype, val); if (*line == '.') { - sprintf(out + strlen(out), "*%s=%s:", fmttype, val); + sprintf(ls_out + strlen(ls_out), "*%s=%s:", fmttype, val); continue; } else if (*line == '*') { - sprintf(out + strlen(out), "%s=%s:", fmttype, val); + sprintf(ls_out + strlen(ls_out), "%s=%s:", fmttype, val); continue; } for (int i = 0; i < 37; i++) { if (strcmp(fmttype, long_types[i]) == 0) { - sprintf(out + strlen(out), - "%s=%s:", short_types[i], val); + sprintf(ls_out + strlen(ls_out), "%s=%s:", short_types[i], val); + parseansi(val, &color); + if (indexes[i] >= 0) { + lsout[2 * indexes[i]] = color.fg; + lsout[2 * indexes[i] + 1] = color.bg; + } break; } } } fclose(fd); - fprintf(stdout, "%s%s%s\n", prefix, out, suffix); - fprintf(stdout, "%s%s%s\n", lsprefix, tolscolors(out), lssuffix); + fprintf(stdout, "%s%s%s\n", prefix, ls_out, suffix); + fprintf(stdout, "%s%s%s\n", lsprefix, lsout, lssuffix); free(line); - free(out); + free(ls_out); return (0); } -void +static void usage(const char *progname) { char *path; -- cgit v1.2.3-56-ge451