commit: b81805e16c65dfca773baaf66b067d2e3b484f88
parent 0348eb07fd9ad5994a5e318ce1bec0f4c38781a8
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Thu, 1 Jan 2026 08:18:29 +0100
cmd/xcd: code cleanup
Diffstat:
| M | cmd/xcd.c | 231 | +++++++++++++++++++++++++++++-------------------------------------------------- |
| M | test-cmd/xcd | 4 | +++- |
2 files changed, 87 insertions(+), 148 deletions(-)
diff --git a/cmd/xcd.c b/cmd/xcd.c
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: MPL-2.0
#define _POSIX_C_SOURCE 200809L
+#define _XOPEN_SOURCE 700
#include <ctype.h> /* isprint() */
#include <errno.h> /* errno */
#include <math.h> /* sin() */
@@ -10,149 +11,107 @@
#include <stdio.h> /* printf(), fread(), fopen(), fclose() */
#include <string.h> /* memset(), strerror() */
+#ifndef M_PI
+#define 3.14159265358979323846
+#endif
+
struct rgb
{
- double red, green, blue;
+ int r, g, b;
};
static struct rgb
-rgb_char(unsigned char i)
+rgb_char(uint8_t i)
{
double freq = 0.018;
- if(i == 0)
- {
- return (struct rgb){64, 64, 64};
- }
- else
- {
- struct rgb color;
- double pi = 3.14159;
+ if(i == 0) return (struct rgb){64, 64, 64};
- color.red = sin(freq * i + 0 * pi / 3) * 127 + 128;
- color.green = sin(freq * i + 2 * pi / 3) * 127 + 128;
- color.blue = sin(freq * i + 4 * pi / 3) * 127 + 128;
+ struct rgb color;
- return color;
- }
+ color.r = sin(freq * i + 0 * M_PI / 3) * 127 + 128;
+ color.g = sin(freq * i + 2 * M_PI / 3) * 127 + 128;
+ color.b = sin(freq * i + 4 * M_PI / 3) * 127 + 128;
+
+ return color;
}
static int
-print_hex_rgb(unsigned char c)
+print_hex_rgb(uint8_t c)
{
struct rgb color = rgb_char(c);
- int ret = printf("[38;2;%d;%d;%dm%02hhx ", (int)color.red, (int)color.green, (int)color.blue, c);
+ if(printf("\033[38;2;%d;%d;%dm%02hhx ", color.r, color.g, color.b, c) <= 0) return 1;
- return (ret <= 0) ? 1 : 0;
+ return 0;
}
static int
print_xcd_reset()
{
- int ret = printf("[0m[48;2;0;0;0m");
+ if(printf("\033[0m\033[48;2;0;0;0m") <= 0) return 1;
- return (ret <= 0) ? 1 : 0;
+ return 0;
}
static int
print_plain_rgb(char *line, size_t len)
{
- if(print_xcd_reset() != 0)
- {
- return 1;
- }
+ if(print_xcd_reset() != 0) return 1;
- if(printf(" >") <= 0)
- {
- return 1;
- }
+ if(printf(" >") <= 0) return 1;
for(size_t i = 0; i < len; i++)
{
- struct rgb color = rgb_char((unsigned char)line[i]);
- int ret = 0;
-
- ret = printf("[38;2;%d;%d;%dm%c",
- (int)color.red,
- (int)color.green,
- (int)color.blue,
- isprint(line[i]) ? line[i] : '.');
+ struct rgb color = rgb_char(line[i]);
- if(ret <= 0)
- {
+ if(printf(
+ "\033[38;2;%d;%d;%dm%c", color.r, color.g, color.b, isprint(line[i]) ? line[i] : '.') <=
+ 0)
return 1;
- }
}
- if(print_xcd_reset() != 0)
- {
- return 1;
- }
+ if(print_xcd_reset() != 0) return 1;
- if(printf("<") <= 0)
- {
- return 1;
- }
+ if(printf("<") <= 0) return 1;
return 0;
}
#define WIDTH 16
-int
+static int
concat(FILE *stream)
{
- int cols = 0;
- char line[WIDTH];
- char c;
- unsigned int bytes = 0;
- struct rgb pos_rgb;
- int ret = 0;
- errno = 0;
+ long unsigned int bytes = 0;
- memset(&line, 0, WIDTH);
+ errno = 0;
- if(print_xcd_reset() != 0)
- {
- goto werr;
- }
+ if(print_xcd_reset() != 0) goto werr;
- pos_rgb = rgb_char((unsigned char)bytes);
+ struct rgb pos_rgb = rgb_char(bytes);
- ret = printf(
- "[38;2;%d;%d;%dm0x%06x ", (int)pos_rgb.red, (int)pos_rgb.green, (int)pos_rgb.blue, bytes);
- if(ret <= 0)
- {
- goto werr;
- }
+ if(printf("\033[38;2;%d;%d;%dm0x%06lx ", pos_rgb.r, pos_rgb.g, pos_rgb.b, bytes) < 0) goto werr;
+ size_t cols = 0;
+ char line[WIDTH] = "";
+ char c;
while(fread(&c, 1, 1, stream) > 0)
{
if(cols >= WIDTH)
{
- print_plain_rgb(line, (size_t)cols);
+ print_plain_rgb(line, cols);
memset(&line, 0, WIDTH);
- pos_rgb = rgb_char((unsigned char)bytes);
- ret = printf("\n[38;2;%d;%d;%dm0x%06x ",
- (int)pos_rgb.red,
- (int)pos_rgb.green,
- (int)pos_rgb.blue,
- bytes);
- if (ret <= 0)
- {
+ pos_rgb = rgb_char(bytes);
+
+ if(printf("\n\033[38;2;%d;%d;%dm0x%06lx ", pos_rgb.r, pos_rgb.g, pos_rgb.b, bytes) < 0)
goto werr;
- }
cols = 0;
}
- ret = print_hex_rgb((unsigned char)c);
- if(ret != 0)
- {
- goto werr;
- }
+ if(print_hex_rgb(c) != 0) goto werr;
line[cols] = c;
@@ -162,43 +121,23 @@ concat(FILE *stream)
// Fill the rest of the hex space with spaces
for(; cols < WIDTH; cols++)
- {
- ret = printf(" ");
+ if(printf(" ") <= 0) goto werr;
- if(ret <= 0)
- {
- goto werr;
- }
- }
+ if(print_xcd_reset() != 0) goto werr;
- if(print_xcd_reset() != 0)
- {
- goto werr;
- }
+ if(print_plain_rgb(line, cols) != 0) goto werr;
- ret = print_plain_rgb(line, (size_t)cols);
- if(ret != 0)
- {
- goto werr;
- }
+ pos_rgb = rgb_char(bytes);
- pos_rgb = rgb_char((unsigned char)bytes);
- ret = printf(
- "\n[38;2;%d;%d;%dm0x%06x\n", (int)pos_rgb.red, (int)pos_rgb.green, (int)pos_rgb.blue, bytes);
- if(ret <= 0)
- {
+ if(printf("\n\033[38;2;%d;%d;%dm0x%06lx\n", pos_rgb.r, pos_rgb.g, pos_rgb.b, bytes) <= 0)
goto werr;
- }
- if(print_xcd_reset() != 0)
- {
- goto werr;
- }
+ if(print_xcd_reset() != 0) goto werr;
return 0;
werr:
- fprintf(stderr, "\n[0mxcd: Write error: %s\n", strerror(errno));
+ fprintf(stderr, "\n\033[0mxcd: error: Failed writing to stdout: %s\n", strerror(errno));
return 1;
}
@@ -209,51 +148,49 @@ main(int argc, char *argv[])
if(argc <= 1)
{
- if(concat(stdin) != 0)
- {
- err = 1;
- goto cleanup;
- }
+ err = concat(stdin);
+
+ printf("\033[0m");
+ return err;
}
- else
+
+ for(int argi = 1; (err == 0) && (argi < argc); argi++)
{
- for(int argi = 1; (err == 0) && (argi < argc); argi++)
+ if(strncmp(argv[argi], "-", 2) == 0)
{
- if(strncmp(argv[argi], "-", 2) == 0)
- {
- if(concat(stdin) != 0)
- {
- err = 1;
- goto cleanup;
- }
- }
- else
+ if(concat(stdin) != 0)
{
- FILE *file = fopen(argv[argi], "r");
- if(!file)
- {
- fprintf(stderr, "\n[0mxcd: Error opening ‘%s’: %s\n", argv[argi], strerror(errno));
- err = 1;
- goto cleanup;
- }
- else
- {
- err += concat(file);
- err += fclose(file);
-
- if(err != 0)
- {
- fprintf(stderr, "\n[0mxcd: Error closing ‘%s’: %s\n", argv[argi], strerror(errno));
- err = 1;
- goto cleanup;
- }
- }
+ err = 1;
+ break;
}
+
+ continue;
}
- }
-cleanup:
- printf("[0m");
+ FILE *file = fopen(argv[argi], "rb");
+ if(!file)
+ {
+ fprintf(stderr,
+ "\n\033[0mxcd: error: Failed opening file ‘%s’: %s\n",
+ argv[argi],
+ strerror(errno));
+ err = 1;
+ break;
+ }
+
+ err += concat(file);
+
+ if(fclose(file) != 0)
+ {
+ fprintf(stderr,
+ "\n\033[0mxcd: error: Failed closing file ‘%s’: %s\n",
+ argv[argi],
+ strerror(errno));
+ err = 1;
+ break;
+ }
+ }
+ printf("\033[0m");
return err;
}
diff --git a/test-cmd/xcd b/test-cmd/xcd
@@ -28,7 +28,9 @@ noperm_body() {
touch inputs/chmod_000 || atf_fail "touching chmod_000"
chmod 0000 inputs/chmod_000 || atf_fail "chmod 0000 chmod_000"
# shellcheck disable=SC1112
- atf_check -s exit:1 -e 'inline:\n[0mxcd: Error opening ‘inputs/chmod_000’: Permission denied\n' -o 'inline:[0m' ../cmd/xcd inputs/chmod_000
+ atf_check -s exit:1 -e "inline:\n\
+[0mxcd: error: Failed opening file ‘inputs/chmod_000’: Permission denied\n\
+" -o 'inline:[0m' ../cmd/xcd inputs/chmod_000
}
noperm_cleanup() {
chmod 0600 inputs/chmod_000 || atf_fail "chmod 0600 chmod_000"