irccat.c (3651B)
1 /* 2 * misc/irccat.c from hirc - cat(1) that convert mIRC codes to ANSI. 3 * 4 * Copyright (c) 2022 hhvn <dev@hhvn.uk> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 20 #include <stdio.h> 21 #include <ctype.h> 22 #include <fcntl.h> 23 #include <errno.h> 24 #include <string.h> 25 #include <unistd.h> 26 #include <stdlib.h> 27 28 #define FCOLOUR "\x1b[38;5;%dm" 29 #define BCOLOUR "\x1b[48;5;%dm" 30 #define BOLD "\x1b[1m" 31 #define NBOLD "\x1b[22m" 32 #define ITALIC "\x1b[3m" 33 #define NITALIC "\x1b[23m" 34 #define REVERSE "\x1b[7m" 35 #define NREVERSE "\x1b[27m" 36 #define UNDERLINE "\x1b[4m" 37 #define NUNDERLINE "\x1b[24m" 38 #define RESET "\x1b[0m" 39 40 #include "../src/data/colours.h" 41 42 void 43 display(int fd) { 44 char buf[BUFSIZ], *s; 45 ssize_t ret; 46 char colourbuf[2][3]; 47 int colours[2]; 48 int rcolour = 0, bg = 0; 49 int bold = 0; 50 int underline = 0; 51 int reverse = 0; 52 int italic = 0; 53 54 while ((ret = read(fd, buf, sizeof(buf) - 1)) != 0) { 55 buf[ret] = '\0'; 56 for (s = buf; s && *s; s++) { 57 if (rcolour) { 58 if (!bg && !colourbuf[0][0] && isdigit(*s)) { 59 colourbuf[0][0] = *s; 60 continue; 61 } else if (!bg && !colourbuf[0][1] && isdigit(*s)) { 62 colourbuf[0][1] = *s; 63 continue; 64 } else if (!bg && *s == ',') { 65 bg = 1; 66 continue; 67 } else if (bg && !colourbuf[1][0] && isdigit(*s)) { 68 colourbuf[1][0] = *s; 69 continue; 70 } else if (bg && !colourbuf[1][1] && isdigit(*s)) { 71 colourbuf[1][1] = *s; 72 continue; 73 } else { 74 rcolour = bg = 0; 75 colours[0] = colourbuf[0][0] ? atoi(colourbuf[0]) : 99; 76 colours[1] = colourbuf[1][0] ? atoi(colourbuf[1]) : 99; 77 78 if (colours[0] != 99) 79 printf(FCOLOUR, colourmap[colours[0]]); 80 if (colours[1] != 99) 81 printf(BCOLOUR, colourmap[colours[1]]); 82 } 83 } 84 85 switch (*s) { 86 case 2: /* ^B */ 87 if (bold) 88 printf(NBOLD); 89 else 90 printf(BOLD); 91 bold = !bold; 92 break; 93 case 3: /* ^C */ 94 memset(colourbuf, '\0', sizeof(colourbuf)); 95 rcolour = 1; 96 break; 97 case 9: /* ^I */ 98 if (italic) 99 printf(NITALIC); 100 else 101 printf(ITALIC); 102 italic = !italic; 103 break; 104 case 15: /* ^O */ 105 bold = underline = reverse = italic = 0; 106 printf(RESET); 107 break; 108 case 18: /* ^R */ 109 if (reverse) 110 printf(NREVERSE); 111 else 112 printf(REVERSE); 113 reverse = !reverse; 114 break; 115 case 21: /* ^U */ 116 if (underline) 117 printf(NUNDERLINE); 118 else 119 printf(UNDERLINE); 120 underline = !underline; 121 break; 122 case '\n': 123 bold = underline = reverse = italic = 0; 124 printf(RESET); 125 /* fallthrough */ 126 default: 127 putchar(*s); 128 break; 129 } 130 } 131 } 132 } 133 134 int 135 main(int argc, char *argv[]) { 136 int i; 137 FILE *f; 138 139 if (argc < 2) { 140 display(0); 141 } else { 142 for (i = 1; i < argc; i++) { 143 if (strcmp(argv[i], "-") == 0) { 144 display(0); 145 } else if ((f = fopen(argv[i], "r")) == NULL) { 146 fprintf(stderr, "could not read '%s': %s\n", argv[i], strerror(errno)); 147 } else { 148 display(fileno(f)); 149 fclose(f); 150 } 151 } 152 } 153 }