diff options
Diffstat (limited to 'Src/Modules')
-rw-r--r-- | Src/Modules/clone.c | 3 | ||||
-rw-r--r-- | Src/Modules/datetime.c | 64 | ||||
-rw-r--r-- | Src/Modules/db_gdbm.c | 2 | ||||
-rw-r--r-- | Src/Modules/nearcolor.c | 210 | ||||
-rw-r--r-- | Src/Modules/nearcolor.mdd | 5 | ||||
-rw-r--r-- | Src/Modules/parameter.c | 44 | ||||
-rw-r--r-- | Src/Modules/stat.c | 4 |
7 files changed, 288 insertions, 44 deletions
diff --git a/Src/Modules/clone.c b/Src/Modules/clone.c index ef6275dcf..4b2655505 100644 --- a/Src/Modules/clone.c +++ b/Src/Modules/clone.c @@ -96,7 +96,8 @@ bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) init_io(NULL); setsparam("TTY", ztrdup(ttystrname)); } - close(ttyfd); + else + close(ttyfd); if (pid < 0) { zerrnam(nam, "fork failed: %e", errno); return 1; diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index be378b347..18c7fb58e 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -100,8 +100,8 @@ output_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) { int bufsize, x, len; char *endptr = NULL, *scalar = NULL, *buffer; - time_t secs; - struct tm *t; + struct tm *tm; + struct timespec ts; if (OPT_ISSET(ops,'s')) { scalar = OPT_ARG(ops, 's'); @@ -110,30 +110,58 @@ output_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) return 1; } } - if (OPT_ISSET(ops, 'r')) + if (OPT_ISSET(ops, 'r')) { + if (!argv[1]) { + zwarnnam(nam, "timestring expected"); + return 1; + } return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q')); - - errno = 0; - secs = (time_t)strtoul(argv[1], &endptr, 10); - if (errno != 0) { - zwarnnam(nam, "%s: %e", argv[1], errno); - return 1; - } else if (*endptr != '\0') { - zwarnnam(nam, "%s: invalid decimal number", argv[1]); - return 1; } - t = localtime(&secs); - if (!t) { - zwarnnam(nam, "%s: unable to convert to time", argv[1]); - return 1; + if (!argv[1]) { + zgettime(&ts); + tm = localtime(&ts.tv_sec); + } else { + errno = 0; + + ts.tv_sec = (time_t)strtoul(argv[1], &endptr, 10); + if (errno != 0) { + zwarnnam(nam, "%s: %e", argv[1], errno); + return 1; + } else if (*argv[1] == '\0' || *endptr != '\0') { + zwarnnam(nam, "%s: invalid decimal number", argv[1]); + return 1; + } + + tm = localtime(&ts.tv_sec); + if (!tm) { + zwarnnam(nam, "%s: unable to convert to time", argv[1]); + return 1; + } + + ts.tv_nsec = 0L; + if (argv[2]) { + ts.tv_nsec = (long)zstrtol(argv[2], &endptr, 10); + if (errno != 0) { + zwarnnam(nam, "%s: %e", argv[2], errno); + return 1; + } else if (*argv[2] == '\0' || *endptr != '\0') { + zwarnnam(nam, "%s: invalid decimal number", argv[2]); + return 1; + } else if (ts.tv_nsec < 0) { + zwarnnam(nam, "%s: invalid nanosecond value", argv[2]); + return 1; + } + } } + bufsize = strlen(argv[0]) * 8; buffer = zalloc(bufsize); len = 0; for (x=0; x < 4; x++) { - if ((len = ztrftime(buffer, bufsize, argv[0], t, 0L)) >= 0 || x==3) + if ((len = ztrftime(buffer, bufsize, argv[0], tm, ts.tv_nsec)) >= 0 || + x==3) break; buffer = zrealloc(buffer, bufsize *= 2); } @@ -207,7 +235,7 @@ getcurrenttime(UNUSED(Param pm)) } static struct builtin bintab[] = { - BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "qrs:", NULL), + BUILTIN("strftime", 0, bin_strftime, 1, 3, 0, "qrs:", NULL), }; static const struct gsu_integer epochseconds_gsu = diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index ed702b912..12dd839cf 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -809,7 +809,7 @@ myfreeparamnode(HashNode hn) zsfree(pm->node.nam); /* If this variable was tied by the user, ename was ztrdup'd */ - if (pm->node.flags & PM_TIED && pm->ename) { + if (!(pm->node.flags & PM_SPECIAL) && pm->ename) { zsfree(pm->ename); pm->ename = NULL; } diff --git a/Src/Modules/nearcolor.c b/Src/Modules/nearcolor.c new file mode 100644 index 000000000..b49ee9afb --- /dev/null +++ b/Src/Modules/nearcolor.c @@ -0,0 +1,210 @@ +/* + * nearcolor.c - map colours to nearest match in 88 or 256 colour palette + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 2018 Oliver Kiddle + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Oliver Kiddle or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Oliver Kiddle and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Oliver Kiddle and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Oliver Kiddle and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "nearcolor.mdh" +#include "nearcolor.pro" + +#include <math.h> + +struct cielab { + double L, a, b; +}; +typedef struct cielab *Cielab; + +static double +deltae(Cielab lab1, Cielab lab2) +{ + /* taking square root unnecessary as we're just comparing values */ + return pow(lab1->L - lab2->L, 2) + + pow(lab1->a - lab2->a, 2) + + pow(lab1->b - lab2->b, 2); +} + +static void +RGBtoLAB(int red, int green, int blue, Cielab lab) +{ + double R = red / 255.0; + double G = green / 255.0; + double B = blue / 255.0; + R = 100.0 * (R > 0.04045 ? pow((R + 0.055) / 1.055, 2.4) : R / 12.92); + G = 100.0 * (G > 0.04045 ? pow((G + 0.055) / 1.055, 2.4) : G / 12.92); + B = 100.0 * (B > 0.04045 ? pow((B + 0.055) / 1.055, 2.4) : B / 12.92); + + /* Observer. = 2 degrees, Illuminant = D65 */ + double X = (R * 0.4124 + G * 0.3576 + B * 0.1805) / 95.047; + double Y = (R * 0.2126 + G * 0.7152 + B * 0.0722) / 100.0; + double Z = (R * 0.0193 + G * 0.1192 + B * 0.9505) / 108.883; + + X = (X > 0.008856) ? pow(X, 1.0/3.0) : (7.787 * X) + (16.0 / 116.0); + Y = (Y > 0.008856) ? pow(Y, 1.0/3.0) : (7.787 * Y) + (16.0 / 116.0); + Z = (Z > 0.008856) ? pow(Z, 1.0/3.0) : (7.787 * Z) + (16.0 / 116.0); + + lab->L = (116.0 * Y) - 16.0; + lab->a = 500.0 * (X - Y); + lab->b = 200.0 * (Y - Z); +} + +static int +mapRGBto88(int red, int green, int blue) +{ + int component[] = { 0, 0x8b, 0xcd, 0xff, 0x2e, 0x5c, 0x8b, 0xa2, 0xb9, 0xd0, 0xe7 }; + struct cielab orig, next; + double nextl, bestl = -1; + int r, g, b; + int comp_r = 0, comp_g = 0, comp_b = 0; + + /* Get original value */ + RGBtoLAB(red, green, blue, &orig); + + /* try every one of the 72 colours */ + for (r = 0; r < 11; r++) { + for (g = 0; g <= 3; g++) { + for (b = 0; b <= 3; b++) { + if (r > 3) g = b = r; /* advance inner loops to the block of greys */ + RGBtoLAB(component[r], component[g], component[b], &next); + nextl = deltae(&orig, &next); + if (nextl < bestl || bestl < 0) { + bestl = nextl; + comp_r = r; + comp_g = g; + comp_b = b; + } + } + } + } + + return (comp_r > 3) ? 77 + comp_r : + 16 + (comp_r * 16) + (comp_g * 4) + comp_b; +} + +/* + * Convert RGB to nearest colour in the 256 colour range + */ +static int +mapRGBto256(int red, int green, int blue) +{ + int component[] = { + 0, 0x5f, 0x87, 0xaf, 0xd7, 0xff, + 0x8, 0x12, 0x1c, 0x26, 0x30, 0x3a, 0x44, 0x4e, + 0x58, 0x62, 0x6c, 0x76, 0x80, 0x8a, 0x94, 0x9e, + 0xa8, 0xb2, 0xbc, 0xc6, 0xd0, 0xda, 0xe4, 0xee + }; + struct cielab orig, next; + double nextl, bestl = -1; + int r, g, b; + int comp_r = 0, comp_g = 0, comp_b = 0; + + /* Get original value */ + RGBtoLAB(red, green, blue, &orig); + + for (r = 0; r < sizeof(component)/sizeof(*component); r++) { + for (g = 0; g <= 5; g++) { + for (b = 0; b <= 5; b++) { + if (r > 5) g = b = r; /* advance inner loops to the block of greys */ + RGBtoLAB(component[r], component[g], component[b], &next); + nextl = deltae(&orig, &next); + if (nextl < bestl || bestl < 0) { + bestl = nextl; + comp_r = r; + comp_g = g; + comp_b = b; + } + } + } + } + + return (comp_r > 5) ? 226 + comp_r : + 16 + (comp_r * 36) + (comp_g * 6) + comp_b; +} + +static int +getnearestcolor(UNUSED(Hookdef dummy), Color_rgb col) +{ + /* we add 1 to the colours so that colour 0 (black) is + * distinguished from runhookdef() indicating that no + * hook function is registered */ + if (tccolours == 256) + return mapRGBto256(col->red, col->green, col->blue) + 1; + if (tccolours == 88) + return mapRGBto88(col->red, col->green, col->blue) + 1; + return -1; +} + +static struct features module_features = { + NULL, 0, + NULL, 0, + NULL, 0, + NULL, 0, + 0 +}; + +/**/ +int +setup_(UNUSED(Module m)) +{ + return 0; +} + +/**/ +int +features_(Module m, char ***features) +{ + *features = featuresarray(m, &module_features); + return 0; +} + +/**/ +int +enables_(Module m, int **enables) +{ + return handlefeatures(m, &module_features, enables); +} + +/**/ +int +boot_(Module m) +{ + addhookfunc("get_color_attr", (Hookfn) getnearestcolor); + return 0; +} + +/**/ +int +cleanup_(Module m) +{ + deletehookfunc("get_color_attr", (Hookfn) getnearestcolor); + return setfeatureenables(m, &module_features, NULL); +} + +/**/ +int +finish_(UNUSED(Module m)) +{ + return 0; +} diff --git a/Src/Modules/nearcolor.mdd b/Src/Modules/nearcolor.mdd new file mode 100644 index 000000000..2fcdaf04e --- /dev/null +++ b/Src/Modules/nearcolor.mdd @@ -0,0 +1,5 @@ +name=zsh/nearcolor +link=dynamic +load=no + +objects="nearcolor.o" diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index 783c36df3..76824cf58 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -75,6 +75,8 @@ paramtypestr(Param pm) val = dyncat(val, "-readonly"); if (f & PM_TAGGED) val = dyncat(val, "-tag"); + if (f & PM_TIED) + val = dyncat(val, "-tied"); if (f & PM_EXPORTED) val = dyncat(val, "-export"); if (f & PM_UNIQUE) @@ -2194,67 +2196,67 @@ static const struct gsu_array historywords_gsu = static struct paramdef partab[] = { SPECIALPMDEF("aliases", 0, &pmraliases_gsu, getpmralias, scanpmraliases), - SPECIALPMDEF("builtins", PM_READONLY, NULL, getpmbuiltin, scanpmbuiltins), + SPECIALPMDEF("builtins", PM_READONLY_SPECIAL, NULL, getpmbuiltin, scanpmbuiltins), SPECIALPMDEF("commands", 0, &pmcommands_gsu, getpmcommand, scanpmcommands), SPECIALPMDEF("dirstack", PM_ARRAY, &dirs_gsu, NULL, NULL), SPECIALPMDEF("dis_aliases", 0, &pmdisraliases_gsu, getpmdisralias, scanpmdisraliases), - SPECIALPMDEF("dis_builtins", PM_READONLY, + SPECIALPMDEF("dis_builtins", PM_READONLY_SPECIAL, NULL, getpmdisbuiltin, scanpmdisbuiltins), SPECIALPMDEF("dis_functions", 0, &pmdisfunctions_gsu, getpmdisfunction, scanpmdisfunctions), - SPECIALPMDEF("dis_functions_source", PM_READONLY, NULL, + SPECIALPMDEF("dis_functions_source", PM_READONLY_SPECIAL, NULL, getpmdisfunction_source, scanpmdisfunction_source), SPECIALPMDEF("dis_galiases", 0, &pmdisgaliases_gsu, getpmdisgalias, scanpmdisgaliases), - SPECIALPMDEF("dis_patchars", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("dis_patchars", PM_ARRAY|PM_READONLY_SPECIAL, &dispatchars_gsu, NULL, NULL), - SPECIALPMDEF("dis_reswords", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("dis_reswords", PM_ARRAY|PM_READONLY_SPECIAL, &disreswords_gsu, NULL, NULL), SPECIALPMDEF("dis_saliases", 0, &pmdissaliases_gsu, getpmdissalias, scanpmdissaliases), - SPECIALPMDEF("funcfiletrace", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("funcfiletrace", PM_ARRAY|PM_READONLY_SPECIAL, &funcfiletrace_gsu, NULL, NULL), - SPECIALPMDEF("funcsourcetrace", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("funcsourcetrace", PM_ARRAY|PM_READONLY_SPECIAL, &funcsourcetrace_gsu, NULL, NULL), - SPECIALPMDEF("funcstack", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("funcstack", PM_ARRAY|PM_READONLY_SPECIAL, &funcstack_gsu, NULL, NULL), SPECIALPMDEF("functions", 0, &pmfunctions_gsu, getpmfunction, scanpmfunctions), - SPECIALPMDEF("functions_source", PM_READONLY, NULL, + SPECIALPMDEF("functions_source", PM_READONLY_SPECIAL, NULL, getpmfunction_source, scanpmfunction_source), - SPECIALPMDEF("functrace", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("functrace", PM_ARRAY|PM_READONLY_SPECIAL, &functrace_gsu, NULL, NULL), SPECIALPMDEF("galiases", 0, &pmgaliases_gsu, getpmgalias, scanpmgaliases), - SPECIALPMDEF("history", PM_READONLY, + SPECIALPMDEF("history", PM_READONLY_SPECIAL, NULL, getpmhistory, scanpmhistory), - SPECIALPMDEF("historywords", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("historywords", PM_ARRAY|PM_READONLY_SPECIAL, &historywords_gsu, NULL, NULL), - SPECIALPMDEF("jobdirs", PM_READONLY, + SPECIALPMDEF("jobdirs", PM_READONLY_SPECIAL, NULL, getpmjobdir, scanpmjobdirs), - SPECIALPMDEF("jobstates", PM_READONLY, + SPECIALPMDEF("jobstates", PM_READONLY_SPECIAL, NULL, getpmjobstate, scanpmjobstates), - SPECIALPMDEF("jobtexts", PM_READONLY, + SPECIALPMDEF("jobtexts", PM_READONLY_SPECIAL, NULL, getpmjobtext, scanpmjobtexts), - SPECIALPMDEF("modules", PM_READONLY, + SPECIALPMDEF("modules", PM_READONLY_SPECIAL, NULL, getpmmodule, scanpmmodules), SPECIALPMDEF("nameddirs", 0, &pmnameddirs_gsu, getpmnameddir, scanpmnameddirs), SPECIALPMDEF("options", 0, &pmoptions_gsu, getpmoption, scanpmoptions), - SPECIALPMDEF("parameters", PM_READONLY, + SPECIALPMDEF("parameters", PM_READONLY_SPECIAL, NULL, getpmparameter, scanpmparameters), - SPECIALPMDEF("patchars", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("patchars", PM_ARRAY|PM_READONLY_SPECIAL, &patchars_gsu, NULL, NULL), - SPECIALPMDEF("reswords", PM_ARRAY|PM_READONLY, + SPECIALPMDEF("reswords", PM_ARRAY|PM_READONLY_SPECIAL, &reswords_gsu, NULL, NULL), SPECIALPMDEF("saliases", 0, &pmsaliases_gsu, getpmsalias, scanpmsaliases), - SPECIALPMDEF("userdirs", PM_READONLY, + SPECIALPMDEF("userdirs", PM_READONLY_SPECIAL, NULL, getpmuserdir, scanpmuserdirs), - SPECIALPMDEF("usergroups", PM_READONLY, + SPECIALPMDEF("usergroups", PM_READONLY_SPECIAL, NULL, getpmusergroups, scanpmusergroups) }; diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index 50a6a9bb2..7c736072b 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -198,10 +198,8 @@ stattimeprint(time_t tim, long nsecs, char *outbuf, int flags) if (flags & STF_STRING) { char *oend = outbuf + strlen(outbuf); /* Where the heck does "40" come from? */ - int len = ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) : + ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) : localtime(&tim), nsecs); - if (len > 0) - metafy(oend, len, META_NOALLOC); if (flags & STF_RAW) strcat(oend, ")"); } |