lolcat.c (1876B)
- // Collection of Unix tools, comparable to coreutils
- // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
- #define _POSIX_C_SOURCE 200809L
- #include <errno.h> /* errno */
- #include <math.h> /* sin() */
- #include <stdio.h> /* fgetc(), fputc(), printf(), fopen(), fclose() */
- #include <string.h> /* strerror() */
- void
- rainbow(double freq, int i)
- {
- double red, green, blue;
- double pi = 3.14159;
- red = sin(freq * i + 0) * 127 + 128;
- green = sin(freq * i + 2 * pi / 3) * 127 + 128;
- blue = sin(freq * i + 4 * pi / 3) * 127 + 128;
- printf("[38;2;%02d;%02d;%02dm", (int)red, (int)green, (int)blue);
- }
- int
- concat(FILE *stream)
- {
- double freq = 0.1;
- int i = 0;
- int c;
- errno = 0;
- while((c = fgetc(stream)) != EOF)
- {
- rainbow(freq, i);
- i++;
- if(c == '')
- {
- printf("[1m^[[0m");
- continue;
- }
- if(fputc(c, stdout) == EOF)
- {
- fprintf(stderr, "\n[0mWrite error: %s\n", strerror(errno));
- return 1;
- }
- }
- if(c == EOF && errno != 0)
- {
- fprintf(stderr, "\n[0mRead error: %s\n", strerror(errno));
- return 1;
- }
- return 0;
- }
- int
- main(int argc, char *argv[])
- {
- int ret = 0;
- if(argc <= 1)
- {
- ret = concat(stdin);
- goto end;
- }
- for(int argi = 1; argi < argc; argi++)
- {
- if(strncmp(argv[argi], "-", 2) == 0)
- {
- ret = concat(stdin);
- if(ret != 0)
- {
- goto end;
- }
- }
- else if(strncmp(argv[argi], "--", 3) == 0)
- {
- continue;
- }
- else
- {
- FILE *file = fopen(argv[argi], "r");
- if(!file)
- {
- fprintf(stderr, "\n[0mError opening ā%sā: %s\n", argv[argi], strerror(errno));
- ret = 1;
- goto end;
- }
- else
- {
- ret = concat(file);
- if(ret != 0)
- {
- goto end;
- }
- ret = fclose(file);
- if(ret != 0)
- {
- goto end;
- }
- }
- }
- }
- end:
- printf("[0m");
- return ret;
- }