hirc

[archived] IRC client
git clone https://hhvn.uk/hirc
git clone git://hhvn.uk/hirc
Log | Files | Refs

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 }