diff options
Diffstat (limited to 'lolcat.c')
-rw-r--r-- | lolcat.c | 88 |
1 files changed, 70 insertions, 18 deletions
@@ -13,6 +13,9 @@ * 0. You just DO WHAT THE FUCK YOU WANT TO. */ +#define _GNU_SOURCE //for fmemopen + +#include <stdint.h> #include <stdio.h> #include <wchar.h> #include <ctype.h> @@ -21,9 +24,35 @@ #include <stdlib.h> #include <string.h> #include <locale.h> +#include <unistd.h> +#include <sys/time.h> + +#include "fgetwc_fix.h" + + +static char helpstr[] = "\n" +"Usage: lolcat [-h horizontal_speed] [-v vertical_speed] [--] [FILES...]\n" +"\n" +"Concatenate FILE(s), or standard input, to standard output.\n" +"With no FILE, or when FILE is -, read standard input.\n" +"\n" +" -h <d>: Horizontal rainbow frequency (default: 0.23)\n" +" -v <d>: Vertical rainbow frequency (default: 0.1)\n" +" -f: Force color even when stdout is not a tty\n" +" --version: Print version and exit\n" +" --help: Show this message\n" +"\n" +"Examples:\n" +" lolcat f - g Output f's contents, then stdin, then g's contents.\n" +" lolcat Copy standard input to standard output.\n" +" fortune | lolcat Display a rainbow cookie.\n" +"\n" +"Report lolcat bugs to <http://www.github.org/jaseg/lolcat/issues>\n" +"lolcat home page: <http://www.github.org/jaseg/lolcat/>\n" +"Original idea: <http://www.github.org/busyloop/lolcat/>\n"; #define ARRAY_SIZE(foo) (sizeof(foo)/sizeof(foo[0])) -char codes[] = {39,38,44,43,49,48,84,83,119,118,154,148,184,178,214,208,209,203,204,198,199,163,164,128,129,93,99,63,69,33}; +const char codes[] = {39,38,44,43,49,48,84,83,119,118,154,148,184,178,214,208,209,203,204,198,199,163,164,128,129,93,99,63,69,33}; /* CAUTION! this function uses a function-static variable! */ void find_escape_sequences(int c, int *state){ @@ -43,10 +72,20 @@ void usage(){ exit(1); } +void version(){ + printf("lolcat version 0.1, (c) 2014 jaseg\n"); + exit(0); +} + int main(int argc, char **argv){ int c, cc=-1, i, l=0; + int colors=(isatty(1) == 1); double freq_h = 0.23, freq_v = 0.1; + struct timeval tv; + gettimeofday(&tv, NULL); + double offx = (tv.tv_sec%300)/300.0; + for(i=1;i<argc;i++){ char *endptr; if(!strcmp(argv[i], "-h")){ @@ -65,6 +104,10 @@ int main(int argc, char **argv){ }else{ usage(); } + }else if(!strcmp(argv[i], "-f")){ + colors = 1; + }else if(!strcmp(argv[i], "--version")){ + version(); }else{ if(!strcmp(argv[i], "--")) i++; @@ -87,20 +130,29 @@ int main(int argc, char **argv){ FILE *f = stdin; int escape_state = 0; - if(strcmp(*filename, "-")) + if(!strcmp(*filename, "--help")) + f = fmemopen(helpstr, strlen(helpstr), "r"); + else if(strcmp(*filename, "-")) f = fopen(*filename, "r"); - - while((c = fgetwc(f)) > 0){ - find_escape_sequences(c, &escape_state); - - if(!escape_state){ - if(c == '\n'){ - l++; - i = 0; - }else if(!iscntrl(c)){ - int ncc = (int)((i++)*freq_h + l*freq_v); - if(cc != ncc) - printf("\033[38;5;%hhum", codes[(cc = ncc) % ARRAY_SIZE(codes)]); + + if(!f){ + fprintf(stderr, "Cannot open input file \"%s\": %s\n", *filename, strerror(errno)); + return 2; + } + + while((c = _fgetwc_fixed(f)) > 0){ + if(colors){ + find_escape_sequences(c, &escape_state); + + if(!escape_state){ + if(c == '\n'){ + l++; + i = 0; + }else if(!iscntrl(c)){ + int ncc = offx*ARRAY_SIZE(codes) + (int)((i++)*freq_h + l*freq_v); + if(cc != ncc) + printf("\033[38;5;%hhum", codes[(cc = ncc) % ARRAY_SIZE(codes)]); + } } } @@ -110,11 +162,11 @@ int main(int argc, char **argv){ printf("\033[38;5;%hhum", codes[cc % ARRAY_SIZE(codes)]); } - if(c != WEOF){ - fprintf(stderr, "Error reading input file \"%s\": %s (%d)\n", *filename, strerror(errno), errno); + fclose(f); + + if(c != WEOF && c != 0){ + fprintf(stderr, "Error reading input file \"%s\": %s\n", *filename, strerror(errno)); return 2; } - - fclose(f); } } |