diff --git a/.gitignore b/.gitignore index 12b43b0..a464544 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ lolcat.o censor.o +lolcat +censor diff --git a/Makefile b/Makefile index 9ce889d..c751508 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CC ?= gcc CFLAGS ?= -std=c11 -Wall -Wextra -O3 -Wno-sign-compare LIBS := -lm -DESTDIR ?= /usr/local/bin +PREFIX ?= /usr/local all: lolcat censor @@ -16,14 +16,14 @@ xterm256lut.h: xterm256lut_gen.py python $< > $@ lolcat: lolcat.c xterm256lut.h - $(CC) $(CFLAGS) -o $@ $< $(LIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) censor: censor.c - $(CC) $(CFLAGS) -o $@ $< $(LIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) install: lolcat censor - install lolcat $(DESTDIR)/lolcat - install censor $(DESTDIR)/censor + install lolcat $(DESTDIR)$(PREFIX)/bin/lolcat + install censor $(DESTDIR)$(PREFIX)/bin/censor clean: rm -f lolcat censor diff --git a/PKGBUILD b/PKGBUILD index 5c2652e..baec990 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Ricardo (XenGi) Band pkgname=c-lolcat -pkgver=v1.3 +pkgver=v1.5 pkgrel=1 pkgdesc="High-performance implementation of lolcat" arch=('i686' 'x86_64') diff --git a/README.md b/README.md index f2d4af9..602a390 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # What? -![](https://raw.githubusercontent.com/jaseg/lolcat/master/LOLCat-Rainbow.jpg) +![](./LOLCat-Rainbow.jpg) ## Screenshot -![](https://raw.githubusercontent.com/jaseg/lolcat/master/screenshot.png) +![](./screenshot.png) ![](./sl.gif) @@ -44,6 +44,8 @@ $ make lolcat ### Others +Note: Debian users may need the `python-is-python3` package. + ```bash $ make && sudo make install ``` diff --git a/autotools/configure.ac b/autotools/configure.ac index 8b9871b..28f5d08 100644 --- a/autotools/configure.ac +++ b/autotools/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([lolcat], [1.3], [jaseg ]) +AC_INIT([lolcat], [1.5], [jaseg ]) AC_CONFIG_SRCDIR([../lolcat.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([autoscripts]) diff --git a/do_release.sh b/do_release.sh new file mode 100755 index 0000000..4d437e8 --- /dev/null +++ b/do_release.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +set -e + +if [ $# -lt 1 ]; then + echo "do_release.sh must be called with a version number as its first argument." + exit 1 +fi + +if [ -n "$(git status --porcelain|grep -v '^??')" ]; then + echo "do_release.sh must be called from a clean working directory." + exit 2 +fi + +VER="$1" + +if echo "$VER" | grep -v '^[0-9]\+\.[0-9]\+$'; then + echo "do_release.sh must be called with a version number formatted like "1.23" as its first argument, with no leading \"v\"." + exit 1 +fi + +echo "Updating files for version v$VER" + +sed -i "/L\"lolcat version [0-9.]\+, (c) [0-9]\+ jaseg\\\\n\"/s/version [0-9.]\+/version $VER/" lolcat.c +sed -i "s/^pkgver=v[0-9.]\+/pkgver=v$VER/" PKGBUILD +sed -i "/^AC_INIT/s/\[[0-9.]\+\]/[$VER]/" autotools/configure.ac +git add lolcat.c PKGBUILD autotools/configure.ac +git commit -m 'Bump version to v$VER' +git tag "v$VER" +echo "Success." + diff --git a/lolcat.c b/lolcat.c index 38b4198..011f5dc 100755 --- a/lolcat.c +++ b/lolcat.c @@ -110,12 +110,28 @@ enum esc_st { ST_ESC_STRING_TERM, ST_ESC_CSI_TERM, ST_ESC_TERM, + NUM_ST +}; + +const char * esc_st_names[NUM_ST] = { + [ST_NONE] = "NONE", + [ST_ESC_BEGIN] = "BEGIN", + [ST_ESC_STRING] = "STRING", + [ST_ESC_CSI] = "CSI", + [ST_ESC_STRING_TERM] = "STRING_TERM", + [ST_ESC_CSI_TERM] = "CSI_TERM", + [ST_ESC_TERM] = "TERM", }; static enum esc_st find_escape_sequences(wint_t c, enum esc_st st) { - if (st == ST_NONE && c == '\033') { /* Escape sequence YAY */ - return ST_ESC_BEGIN; + + if (st == ST_NONE || st == ST_ESC_CSI_TERM) { + if (c == '\033') { /* Escape sequence YAY */ + return ST_ESC_BEGIN; + } else { + return ST_NONE; + } } else if (st == ST_ESC_BEGIN) { if (c == '[') { @@ -134,7 +150,9 @@ static enum esc_st find_escape_sequences(wint_t c, enum esc_st st) } } else if (st == ST_ESC_STRING) { - if (c == '\033') { + if (c == '\007') { + return ST_NONE; + } else if (c == '\033') { return ST_ESC_STRING_TERM; } else { return st; @@ -142,7 +160,7 @@ static enum esc_st find_escape_sequences(wint_t c, enum esc_st st) } else if (st == ST_ESC_STRING_TERM) { if (c == '\\') { - return ST_ESC_TERM; + return ST_NONE; } else { return ST_ESC_STRING; } @@ -155,12 +173,14 @@ static enum esc_st find_escape_sequences(wint_t c, enum esc_st st) static void usage(void) { wprintf(L"Usage: lolcat [-h horizontal_speed] [-v vertical_speed] [--] [FILES...]\n"); + wprintf(L"\n"); + wprintf(L"Use lolcat --help to print the full help text.\n"); exit(2); } static void version(void) { - wprintf(L"lolcat version 1.3, (c) 2020 jaseg\n"); + wprintf(L"lolcat version 1.5, (c) 2024 jaseg\n"); exit(0); } @@ -355,19 +375,34 @@ int main(int argc, char** argv) while ((c = this_file_read_wchar(f)) != WEOF) { if (colors) { - escape_state = find_escape_sequences(c, escape_state); - if (!escape_state) { + + escape_state = find_escape_sequences(c, escape_state); +#ifdef ESC_DEBUG + fprintf(stderr, "%02x %c %s\n", c, c > 32 ? c : '.', esc_st_names[escape_state]); +#endif + + if (escape_state == ST_ESC_CSI_TERM) { + putwchar(c); + } + + if (escape_state == ST_NONE || escape_state == ST_ESC_CSI_TERM) { if (c == '\n') { l++; i = 0; + cc = -1; if (invert) { wprintf(L"\033[49m"); + } else { + wprintf(L"\033[0m"); } } else { - if (rgb) { + if (escape_state == ST_NONE) { i += wcwidth(c); + } + + if (rgb) { float theta = i * freq_h / 5.0f + l * freq_v + (offx + 2.0f * (rand_offset + start_color) / RAND_MAX)*M_PI; union rgb_c c; @@ -386,15 +421,15 @@ int main(int argc, char** argv) wprintf(L"\033[%d;2;%d;%d;%dm", (invert ? 48 : 38), c.r, c.g, c.b); } else if (ansi16) { - int ncc = offx * ARRAY_SIZE(codes16) + (int)((i += wcwidth(c)) * freq_h + l * freq_v); - if (cc != ncc) { + int ncc = offx * ARRAY_SIZE(codes16) + (int)(i * freq_h + l * freq_v); + if (cc != ncc || escape_state == ST_ESC_CSI_TERM) { wprintf(L"\033[%hhum", (invert ? 10 : 0) + codes16[(rand_offset + start_color + (cc = ncc)) % ARRAY_SIZE(codes16)]); } } else { if (gradient) { - int ncc = offx * ARRAY_SIZE(codes_gradient) + (int)((i += wcwidth(c)) * freq_h + l * freq_v); - if (cc != ncc) { + int ncc = offx * ARRAY_SIZE(codes_gradient) + (int)(i * freq_h + l * freq_v); + if (cc != ncc || escape_state == ST_ESC_CSI_TERM) { size_t lookup = (rand_offset + start_color + (cc = ncc)) % (2*ARRAY_SIZE(codes_gradient)); if (lookup >= ARRAY_SIZE(codes_gradient)) { lookup = 2*ARRAY_SIZE(codes_gradient) - 1 - lookup; @@ -403,8 +438,8 @@ int main(int argc, char** argv) } } else { - int ncc = offx * ARRAY_SIZE(codes) + (int)((i += wcwidth(c)) * freq_h + l * freq_v); - if (cc != ncc) { + int ncc = offx * ARRAY_SIZE(codes) + (int)(i * freq_h + l * freq_v); + if (cc != ncc || escape_state == ST_ESC_CSI_TERM) { wprintf(L"\033[%d;5;%hhum", (invert ? 48 : 38), codes[(rand_offset + start_color + (cc = ncc)) % ARRAY_SIZE(codes)]); } } @@ -413,10 +448,8 @@ int main(int argc, char** argv) } } - putwchar(c); - - if (escape_state == ST_ESC_CSI_TERM) { /* implies "colors" */ - wprintf(L"\033[38;5;%hhum", codes[(rand_offset + start_color + cc) % ARRAY_SIZE(codes)]); + if (escape_state != ST_ESC_CSI_TERM) { + putwchar(c); } }