From 8c30c456806ff6d40684a7acf4084f387932db0e Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Tue, 6 Feb 2024 07:46:58 +0100 Subject: Big update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- mk/conv.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mk/make-dir-info | 49 +++++++++++++++ mk/make-stage-2.mk | 43 +++++++++++++ mk/portable.mk | 86 +++++++++++++++++++++++++ mk/unportable.mk | 22 +++++++ 5 files changed, 380 insertions(+) create mode 100644 mk/conv.c create mode 100755 mk/make-dir-info create mode 100644 mk/make-stage-2.mk create mode 100644 mk/portable.mk create mode 100644 mk/unportable.mk (limited to 'mk') diff --git a/mk/conv.c b/mk/conv.c new file mode 100644 index 0000000..3decbfd --- /dev/null +++ b/mk/conv.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include +#include + +static char *argv0; + + +static int +single(int argc, char *argv[]) +{ + char size[256], target[4096], source[4096]; + char *p; + ssize_t r; + int fd; + + p = strchr(argv[0], 'x'); + if (!p) + return 1; + *p = '\0'; + stpcpy(size, argv[0]); + *p = 'x'; + + p = &p[strcspn(p, "-/")]; + if (!p) + return 1; + p = stpcpy(stpcpy(source, "scalable"), p); + if (strcmp(&p[-4], ".png")) + return 1; + stpcpy(&p[-4], ".svg"); + + for (p = argv[0]; (p = strchr(p, '/')); p++) { + *p = '\0'; + if (mkdir(argv[0], 0777) && errno != EEXIST) { + fprintf(stderr, "%s: mkdir %s 0777: %s\n", argv0, argv[0], strerror(errno)); + return 1; + } + *p = '/'; + } + + r = readlink(source, target, sizeof(target) - 1); + if (r >= 0) + target[r] = 0; + if (r >= 0 && (r >= sizeof(target) - 1 || r < 4 || strcmp(&target[r - 4], ".svg"))) { + return 1; + } else if (r < 0 && errno == EINVAL) { + fd = open(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) { + fprintf(stderr, "%s: open %s O_WRONLY|O_CREAT|O_TRUNC 0666: %s\n", argv0, argv[0], strerror(errno)); + return 1; + } + if (fd != STDOUT_FILENO) { + if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO) + fprintf(stderr, "%s: dup2 %i 1: %s\n", argv0, fd, strerror(errno)); + close(fd); + } + execlp("rsvg-convert", "rsvg-convert", "-w", size, "-h", size, "-f", "png", source, NULL); + fprintf(stderr, "%s: execvp rsvg-convert: %s\n", argv0, strerror(errno)); + return 1; + } else if (r < 0) { + fprintf(stderr, "%s: readlink %s: %s\n", argv0, source, strerror(errno)); + return 1; + } else { + stpcpy(&target[r - 4], ".png"); + if (symlink(target, argv[0])) { + if (errno == EEXIST) { + unlink(argv[0]); + if (!symlink(target, argv[0])) + return 0; + } + fprintf(stderr, "%s: symlink %s %s: %s\n", argv0, target, argv[0], strerror(errno)); + return 1; + } + return 0; + } +} + + +static int +multi(int argc, char *argv[]) +{ + char *source, output[4096], target[4096]; + char *p, *q; + pid_t pid; + int status, fd, i; + ssize_t r; + + source = *argv++, argc--; + + q = &source[strcspn(source, "-/")]; + if (!q) + return 1; + + for (i = 0; i < argc; i++) { + stpcpy(stpcpy(stpcpy(stpcpy(output, argv[i]), "x"), argv[i]), q); + for (p = output; (p = strchr(p, '/')); p++) { + *p = '\0'; + if (mkdir(output, 0777) && errno != EEXIST) { + fprintf(stderr, "%s: mkdir %s 0777: %s\n", argv0, output, strerror(errno)); + return 1; + } + *p = '/'; + } + } + + r = readlink(source, target, sizeof(target) - 1); + if (r >= 0) + target[r] = 0; + if (r >= 0 && (r >= sizeof(target) - 1 || r < 4 || strcmp(&target[r - 4], ".svg"))) { + return 1; + } else if (r < 0 && errno == EINVAL) { + p = stpcpy(stpcpy(stpcpy(stpcpy(output, argv[0]), "x"), argv[0]), q); + stpcpy(&p[-4], ".png"); + for (; *argv; argv++, argc--) { + pid = argc == 1 ? 0 : fork(); + if (pid == -1) { + fprintf(stderr, "%s: fork: %s\n", argv0, strerror(errno)); + return 1; + } + if (pid) { + p = stpcpy(stpcpy(stpcpy(stpcpy(output, argv[1]), "x"), argv[1]), q); + stpcpy(&p[-4], ".png"); + if (waitpid(pid, &status, 0) != pid) { + fprintf(stderr, "%s: waitpid rsvg-convert: %s\n", argv0, strerror(errno)); + return 1; + } + if (status) + return 1; + continue; + } + fd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) { + fprintf(stderr, "%s: open %s O_WRONLY|O_CREAT|O_TRUNC 0666: %s\n", argv0, output, strerror(errno)); + return 1; + } + if (fd != STDOUT_FILENO) { + if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO) + fprintf(stderr, "%s: dup2 %i 1: %s\n", argv0, fd, strerror(errno)); + close(fd); + } + execlp("rsvg-convert", "rsvg-convert", "-w", *argv, "-h", *argv, "-f", "png", source, NULL); + fprintf(stderr, "%s: execvp rsvg-convert: %s\n", argv0, strerror(errno)); + return 1; + } + } else if (r < 0) { + fprintf(stderr, "%s: readlink %s: %s\n", argv0, source, strerror(errno)); + return 1; + } else { + stpcpy(&target[r - 4], ".png"); + for (; *argv; argv++) { + p = stpcpy(stpcpy(stpcpy(stpcpy(output, *argv), "x"), *argv), q); + stpcpy(&p[-4], ".png"); + if (symlink(target, output)) { + if (errno == EEXIST) { + unlink(output); + if (!symlink(target, output)) + continue; + } + fprintf(stderr, "%s: symlink %s %s: %s\n", argv0, target, output, strerror(errno)); + return 1; + } + } + return 0; + } +} + + +int +main(int argc, char *argv[]) +{ + argv0 = *argv++, argc--; + if (argc == 1) + return single(argc, argv); + if (argc > 1) + return multi(argc, argv); + return 1; +} diff --git a/mk/make-dir-info b/mk/make-dir-info new file mode 100755 index 0000000..d2adb6b --- /dev/null +++ b/mk/make-dir-info @@ -0,0 +1,49 @@ +#!/bin/sh + +size="$1" +dir="$2" + +d="$(printf '%s\n' "$dir" | cut -d / -f 1)" + +if test "$d" = actions; then + context=Actions +elif test "$d" = animations; then + context=Animations +elif test "$d" = apps; then + context=Applications +elif test "$d" = categories; then + context=Categories +elif test "$d" = devices; then + context=Devices +elif test "$d" = emblems; then + context=Emblems +elif test "$d" = emotes; then + context=Emotes +elif test "$d" = filesystems; then + context=FileSystems +elif test "$d" = intl; then + context=International +elif test "$d" = legacy; then + context=Legacy +elif test "$d" = mimetypes; then + context=MimeTypes +elif test "$d" = places; then + context=Places +elif test "$d" = status; then + context=Status +elif test "$d" = stock; then + context=Stock +elif test "$d" = ui; then + context=UI +else + printf '%s: No value defined for Context for %s\n' "$0" "$d" >&2 + exit 1 +fi + +if test "$size" = scalable; then + printf '[%s/%s]\n' "$size" "$dir" + printf '%s\n' Context="$context" Size="16" MinSize="8" MaxSize="1024" Type="Scalable" +else + printf '[%sx%s/%s]\n' "$size" "$size" "$dir" + printf '%s\n' Context="$context" Size="$size" Type="Fixed" +fi diff --git a/mk/make-stage-2.mk b/mk/make-stage-2.mk new file mode 100644 index 0000000..08a5a09 --- /dev/null +++ b/mk/make-stage-2.mk @@ -0,0 +1,43 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +DIRS =\ + actions\ + apps\ + categories\ + devices\ + emblems\ + emotes\ + mimetypes\ + places\ + status + +include icons.mk + +all: + +include generated.mk +include mk/portable.mk +include mk/unportable.mk + +# For implementation that do not support pattern matching rules +.DEFAULT: + +@set -e;\ + if printf '%s\n' "$@" | grep '^scalable' > /dev/null; then\ + sed < mk/unportable.mk '1s|%|'"$$(printf '%s\n' "$@" | sed 's|^scalable/\(.*\)\.svg$$|\1|')"'|g' | $(MAKE) -f - "$@";\ + elif printf '%s\n' "$@" | grep '\.png$$' > /dev/null; then\ + printf '%s\n' "$@" >&2 ;\ + $(MAKE) -f mk/make-stage-2.mk conv &&\ + f="$$(printf '%s\n' "$@" | sed 's|^[^/]*\/\(.*\)\.png$$|\1|')" &&\ + if test -n "$(DIR_SUFFIX)"; then \ + $(MAKE) -f mk/make-stage-2.mk scalable$(DIR_SUFFIX)/$$f.svg; \ + fi && \ + sed '/^[a-zA-Z0-9].*=/,$$d' < generated.mk | sed 's|%|'"$$f"'|g' | $(MAKE) -f - "$@";\ + else\ + printf 'No rule to make target %s\n' "$@" >&2;\ + exit 2;\ + fi + +.PHONY: all all-fast all-fast-icons install uninstall clean diff --git a/mk/portable.mk b/mk/portable.mk new file mode 100644 index 0000000..c957871 --- /dev/null +++ b/mk/portable.mk @@ -0,0 +1,86 @@ +all: index.theme $(ALL_PNG_ICONS) + +all-fast: index.theme all-fast-icons + +all-fast-icons: $(ICONS:=.x) + +$(ICONS:=.x): conv + @+test -z "$(DIR_SUFFIX)" || $(MAKE) scalable$(DIR_SUFFIX)/$(@:.x=.svg) + ./conv scalable$(DIR_SUFFIX)/$(@:.x=.svg) $(SIZES) + +index.theme: $(CONFIGFILE) mk/portable.mk mk/make-dir-info + set -e;\ + printf '%s\n' \ + '[Icon Theme]'\ + 'Name=$(THEME_NAME)'\ + 'Comment=$(THEME_DESC)'\ + 'Example=folder'\ + ''\ + '# KDE specific stuff'\ + 'DisplayDepth=32'\ + 'LinkOverlay=link_overlay'\ + 'LockOverlay=lock_overlay'\ + 'ZipOverlay=zip_overlay'\ + 'DesktopDefault=48'\ + 'DesktopSizes='$$(printf ',%s' $(SIZES) | sed 's/^,//')\ + 'ToolbarDefault=22'\ + 'ToolbarSizes=8,16,22,32,48'\ + 'MainToolbarDefault=22'\ + 'MainToolbarSizes=8,16,22,32,48'\ + 'SmallDefault=16'\ + 'SmallSizes=16'\ + 'PanelDefault=32'\ + 'PanelSizes='$$(printf ',%s' $(SIZES) | sed 's/^,//')\ + ''\ + > index.theme + printf 'Directories=' >> index.theme + set -e;\ + for s in $(SIZES); do\ + for d in $(DIRS); do\ + printf ',%sx%s/%s' $$s $$s $$d;\ + done;\ + done | sed 's/^,//' >> index.theme + set -e;\ + for d in $(DIRS); do\ + printf ',scalable/%s' $$d;\ + done >> index.theme + printf '\n' >> index.theme + set -e;\ + for s in $(SIZES) scalable; do\ + for d in $(DIRS); do\ + printf '\n';\ + mk/make-dir-info $$s $$d;\ + done;\ + done >> index.theme + +conv: mk/conv.c + $(CC) -o $@ $< $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + +install: index.theme $(ALL_PNG_ICONS) + mkdir -p -- "$(DESTDIR)$(ICONPREFIX)" + set -e;\ + for d in $(DIRS); do\ + for s in $(SIZES); do\ + mkdir -p -- "$(DESTDIR)$(ICONPREFIX)/$(THEME_DIR)/$${s}x$${s}/$${d}";\ + done;\ + mkdir -p -- "$(DESTDIR)$(ICONPREFIX)/$(THEME_DIR)/scalable/$${d}";\ + done + head -n 1 < icons.mk | grep '^ICONS' > /dev/null + set -e;\ + (sed '/[^\\]$$/q' | sed 's/\\$$//' | sed '1s/^.*=//' | sed 's/[[:space:]]//g' | sed '/^$$/d') < icons.mk |\ + while read i; do\ + for s in $(SIZES); do\ + cp -P -- "$${s}x$${s}$(DIR_SUFFIX)/$${i}.png" "$(DESTDIR)$(ICONPREFIX)/$(THEME_DIR)/$${s}x$${s}/$${i}.png";\ + done;\ + cp -P -- "scalable$(DIR_SUFFIX)/$${i}.svg" "$(DESTDIR)$(ICONPREFIX)/$(THEME_DIR)/scalable/$${i}.svg";\ + done + cp -- index.theme "$(DESTDIR)$(ICONPREFIX)/$(THEME_DIR)/index.theme" + +#`(sed ...) < icons.mk | while read i` is used instead of `for i in $(ICONS)` because $(ICONS) got too big for sh(1) +#The + +uninstall: + -rm -rf -- "$(DESTDIR)$(ICONPREFIX)/$(THEME_DIR)" + +clean: + +@$(MAKE) -f Makefile clean diff --git a/mk/unportable.mk b/mk/unportable.mk new file mode 100644 index 0000000..5d26d20 --- /dev/null +++ b/mk/unportable.mk @@ -0,0 +1,22 @@ +scalable-$(DIR_SUFFIX_)/%.svg: scalable/%.svg + @mkdir -p -- "$$(dirname -- "$@")" + set -e;\ + F=$$(printf '%s\n' "$@" | cut -d / -f 2-);\ + if ! test "$@" = "scalable/$$F"; then\ + if test -L "scalable/$$F"; then\ + ln -sf "$$(readlink -- "scalable/$$F")" "$@";\ + else\ + sed < "scalable/$$F" > "$@"\ + -e 's/#[bB][eE][bB][eE][bB][eE]/#$(BASE_COLOUR)/g'\ + -e 's/#[eE][fF]2929/#$(ALARM_RED)/g'\ + -e 's/#[fF]57900/#$(ALARM_ORANGE)/g'\ + -e 's/#[cC][dD]656[cC]/#$(RED)/g'\ + -e 's/#[dD]69553/#$(ORANGE)/g'\ + -e 's/#[cC][cC][aA][dD]47/#$(YELLOW)/g'\ + -e 's/#32[aA]679/#$(GREEN)/g'\ + -e 's/#00[aA]09[fF]/#$(CYAN)/g'\ + -e 's/#2495[bB][eE]/#$(BLUE)/g'\ + -e 's/#[aA]46[eE][bB]0/#$(MAGENTA)/g'\ + -e 's/#000000/#$(OUTLINE)/g';\ + fi;\ + fi -- cgit v1.2.3-70-g09d2