hirc

IRC client
Log | Files | Refs

commit cce60d0b72958d5c374928f128c806abb66019e1
parent 57a7915f77857922763afb1235a2cfe7752d89f7
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 20 Mar 2022 11:21:12 +0000

Add irccat (converts mirc codes to ansi. Adapted from ui_wprintc)

Diffstat:
M.gitignore | 1+
Amisc/Makefile | 4++++
Amisc/irccat.c | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 174 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +1,4 @@ +misc/irccat hirc hirc.1 *.o diff --git a/misc/Makefile b/misc/Makefile @@ -0,0 +1,4 @@ +irccat: irccat.c + +.c: + cc -o $(<:.c=) $< diff --git a/misc/irccat.c b/misc/irccat.c @@ -0,0 +1,169 @@ +/* + * misc/irccat.c from hirc - cat(1) that convert mIRC codes to ANSI. + * + * Copyright (c) 2022 hhvn <dev@hhvn.uk> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +#define FCOLOUR "\x1b[38;5;%dm" +#define BCOLOUR "\x1b[48;5;%dm" +#define BOLD "\x1b[1m" +#define NBOLD "\x1b[22m" +#define ITALIC "\x1b[3m" +#define NITALIC "\x1b[23m" +#define REVERSE "\x1b[7m" +#define NREVERSE "\x1b[27m" +#define UNDERLINE "\x1b[4m" +#define NUNDERLINE "\x1b[24m" +#define RESET "\x1b[0m" + +#define HIRC_COLOURS 100 +static unsigned short colourmap[HIRC_COLOURS] = { + [0] = 255, 16, 19, 46, 124, 88, 127, 184, + [8] = 208, 46, 45, 51, 21, 201, 240, 255, + + /* extended */ + [16] = 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89, + [28] = 88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125, + [40] = 124, 166, 184, 106, 34, 49, 37, 33, 19, 129, 127, 161, + [52] = 196, 208, 226, 154, 46, 86, 51, 75, 21, 171, 201, 198, + [64] = 203, 215, 227, 191, 83, 122, 87, 111, 63, 177, 207, 205, + [76] = 217, 223, 229, 193, 157, 158, 159, 153, 147, 183, 219, 212, + [88] = 16, 233, 235, 237, 239, 241, 244, 247, 250, 254, 231, + + /* transparency */ + [99] = -1 +}; + +void +display(int fd) { + char buf[BUFSIZ], *s; + ssize_t ret; + char colourbuf[2][3]; + int colours[2]; + int rcolour = 0, bg = 0; + int bold = 0; + int underline = 0; + int reverse = 0; + int italic = 0; + + while ((ret = read(fd, buf, sizeof(buf) - 1)) != 0) { + buf[ret] = '\0'; + for (s = buf; s && *s; s++) { + if (rcolour) { + if (!bg && !colourbuf[0][0] && isdigit(*s)) { + colourbuf[0][0] = *s; + continue; + } else if (!bg && !colourbuf[0][1] && isdigit(*s)) { + colourbuf[0][1] = *s; + continue; + } else if (!bg && *s == ',') { + bg = 1; + continue; + } else if (bg && !colourbuf[1][0] && isdigit(*s)) { + colourbuf[1][0] = *s; + continue; + } else if (bg && !colourbuf[1][1] && isdigit(*s)) { + colourbuf[1][1] = *s; + continue; + } else { + rcolour = bg = 0; + colours[0] = colourbuf[0][0] ? atoi(colourbuf[0]) : 99; + colours[1] = colourbuf[1][0] ? atoi(colourbuf[1]) : 99; + + if (colours[0] != 99) + printf(FCOLOUR, colourmap[colours[0]]); + if (colours[1] != 99) + printf(BCOLOUR, colourmap[colours[1]]); + } + } + + switch (*s) { + case 2: /* ^B */ + if (bold) + printf(NBOLD); + else + printf(BOLD); + bold = !bold; + break; + case 3: /* ^C */ + memset(colourbuf, '\0', sizeof(colourbuf)); + rcolour = 1; + break; + case 9: /* ^I */ + if (italic) + printf(NITALIC); + else + printf(ITALIC); + italic = !italic; + break; + case 15: /* ^O */ + bold = underline = reverse = italic = 0; + printf(RESET); + break; + case 18: /* ^R */ + if (reverse) + printf(NREVERSE); + else + printf(REVERSE); + reverse = !reverse; + break; + case 21: /* ^U */ + if (underline) + printf(NUNDERLINE); + else + printf(UNDERLINE); + underline = !underline; + break; + case '\n': + bold = underline = reverse = italic = 0; + printf(RESET); + /* fallthrough */ + default: + putchar(*s); + break; + } + } + } +} + +int +main(int argc, char *argv[]) { + int i; + FILE *f; + + if (argc < 2) { + display(0); + } else { + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-") == 0) { + display(0); + } else if ((f = fopen(argv[i], "r")) == NULL) { + fprintf(stderr, "could not read '%s': %s\n", argv[i], strerror(errno)); + } else { + display(fileno(f)); + fclose(f); + } + } + } +}