1 #include "config.h"
2 
3 #include "compat.h"
4 
5 #include <stdarg.h>
6 #include <limits.h>
7 #include <ctype.h>
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <assert.h>
11 #include <locale.h>
12 #include <langinfo.h>
13 
14 /*
15     Useful string stuff
16 */
17 
strconcat(char * dest,size_t maxdestlen,const char * src)18 void strconcat
19   (
20     char * dest,
21     size_t maxdestlen,
22     const char * src
23   )
24   /* appends null-terminated src onto dest, ensuring length of contents
25     of latter (including terminating null) do not exceed maxdestlen. */
26   {
27     const size_t destlen = strlen(dest);
28     size_t srclen = strlen(src);
29     assert(destlen < maxdestlen);
30     if (srclen > maxdestlen - 1 - destlen)
31       {
32         srclen = maxdestlen - 1 - destlen;
33       } /*if*/
34     memcpy(dest + destlen, src, srclen);
35     dest[destlen + srclen] = 0;
36   } /*strconcat*/
37 
strtounsigned(const char * s,const char * what)38 unsigned int strtounsigned
39   (
40     const char * s,
41     const char * what /* description of what I'm trying to convert, for error message */
42   )
43   /* parses s as an unsigned decimal integer, returning its value. Aborts the
44     program on error. */
45   {
46     char * s_end;
47     unsigned long result;
48     errno = 0;
49     result = strtoul(s, &s_end, 10);
50     if (errno == 0)
51       {
52         if (*s_end != '\0')
53           {
54             errno = EINVAL;
55           }
56         else if (result > UINT_MAX)
57           {
58             errno = ERANGE;
59           }
60       } /*if*/
61     if (errno != 0)
62       {
63         fprintf(stderr, "ERR:  %d converting %s \"%s\" -- %s\n", errno, what, s, strerror(errno));
64         exit(1);
65       } /*if*/
66     return result;
67   } /*strtounsigned*/
68 
strtosigned(const char * s,const char * what)69 int strtosigned
70   (
71     const char * s,
72     const char * what /* description of what I'm trying to convert, for error message */
73   )
74   /* parses s as a signed decimal integer, returning its value. Aborts the
75     program on error. */
76   {
77     char * s_end;
78     long result;
79     errno = 0;
80     result = strtol(s, &s_end, 10);
81     if (errno == 0)
82       {
83         if (*s_end != '\0')
84           {
85             errno = EINVAL;
86           }
87         else if (result < -INT_MAX || result > INT_MAX)
88           {
89             errno = ERANGE;
90           }
91       } /*if*/
92     if (errno != 0)
93       {
94         fprintf(stderr, "ERR:  %d converting %s \"%s\" -- %s\n", errno, what, s, strerror(errno));
95         exit(1);
96       } /*if*/
97     return result;
98   } /*strtosigned*/
99 
100 #ifndef HAVE_STRNDUP
strndup(const char * s,size_t n)101 char * strndup
102   (
103     const char * s,
104     size_t n
105   )
106   {
107     char * result;
108     size_t l = strlen(s);
109     if (l > n)
110       {
111         l = n;
112       } /*if*/
113     result = malloc(l + 1);
114     memcpy(result, s, l);
115     result[l] = 0;
116     return
117         result;
118   } /*strndup*/
119 #endif /*HAVE_STRNDUP*/
120 
sprintf_alloc(const char * format,...)121 char * sprintf_alloc
122   (
123     const char * format,
124     ...
125   )
126   /* does the equivalent of sprintf(3) on the args, except the output string buffer
127     is dynamically allocated to be exactly big enough to hold the formatted data.
128     The result is the allocated and filled-in string buffer.
129     On failure, the result will be NULL and errno will contain the error. */
130   {
131     char * result = NULL;
132     size_t result_size = 0;
133     bool allocating = false;
134     for (;;)
135       {
136         va_list args;
137         int nrbytes;
138         va_start(args, format);
139         nrbytes = vsnprintf(result, result_size, format, args) + 1;
140         va_end(args);
141         if (allocating)
142             break;
143         result_size = nrbytes;
144         result = malloc(result_size);
145         if (result == NULL)
146             break;
147         allocating = true;
148       } /*for*/
149     return
150         result;
151   } /*sprintf_alloc*/
152 
str_extract_until(const char ** src,const char * delim)153 char * str_extract_until
154   (
155     const char ** src,
156     const char * delim
157   )
158   /* scans *src, looking for the first occurrence of a character in delim. Returns
159     a copy of the prior part of *src if found, and updates *src to point after the
160     delimiter character; else returns a copy of the whole of *src, and sets *src
161     to NULL. Returns NULL iff *src is NULL. */
162   {
163     char * result = NULL; /* to begin with */
164     if (*src != NULL)
165       {
166         const size_t pos = strcspn(*src, delim);
167         if (pos < strlen(*src))
168           {
169             result = strndup(*src, pos);
170             *src = *src + pos + strspn(*src + pos, delim);
171           }
172         else
173           {
174             result = strdup(*src);
175             *src = NULL;
176           } /*if*/
177       } /*if*/
178     return
179         result;
180   } /*str_extract_until*/
181 
182 /*
183     locale stuff
184 */
185 
186 #ifdef HAVE_ICONV
187 
188 const char *
189     default_charset;
190 static char
191     default_charset_buf[32]; /* big enough? */
192 static iconv_t
193     from_locale = ICONV_NULL;
194 
195 #endif /*HAVE_ICONV*/
196 
init_locale()197 void init_locale()
198   /* does locale initialization and obtains the default character set. */
199   {
200 #ifdef HAVE_ICONV
201     setlocale(LC_ALL, "");
202     strncpy(default_charset_buf, nl_langinfo(CODESET), sizeof default_charset_buf - 1);
203     default_charset_buf[sizeof default_charset_buf - 1] = 0;
204     default_charset = default_charset_buf;
205     // fprintf(stderr, "INFO: default codeset is \"%s\"\n", default_charset); /* debug */
206     setlocale(LC_ALL, "C"); /* don't need locale for anything else */
207 #else
208     // fprintf(stderr, "INFO: all text will be interpreted as UTF-8\n"); /* debug */
209 #endif /*HAVE_ICONV*/
210   } /*init_locale*/
211 
locale_decode(const char * localestr)212 char * locale_decode
213   (
214     const char * localestr
215   )
216   /* allocates and returns a string containing the UTF-8 representation of
217     localestr interpreted according to the user's locale settings. */
218   /* not actually used anywhere */
219   {
220     char * result;
221 #ifdef HAVE_ICONV
222     size_t inlen, outlen;
223     char * resultnext;
224     if (from_locale == ICONV_NULL)
225       {
226         from_locale = iconv_open("UTF-8", default_charset);
227         if (from_locale == ICONV_NULL)
228           {
229             fprintf(stderr, "ERR:  Cannot convert from charset \"%s\" to UTF-8\n", default_charset);
230             exit(1);
231           } /*if*/
232       } /*if*/
233     inlen = strlen(localestr);
234     outlen = inlen * 5; /* should be enough? */
235     result = malloc(outlen);
236     resultnext = result;
237     if (iconv(from_locale, (char **)&localestr, &inlen, &resultnext, &outlen) < 0)
238       {
239         fprintf
240           (
241             stderr,
242             "ERR:  Error %d -- %s decoding string \"%s\"\n",
243             errno, strerror(errno), localestr
244           );
245         exit(1);
246       } /*if*/
247     assert(outlen != 0); /* there will be room for ... */
248     *resultnext++ = 0; /* ... terminating null */
249     result = realloc(result, resultnext - result); /* free unneeded memory */
250 #else
251     result = strdup(localestr);
252 #endif /*HAVE_ICONV*/
253     return result;
254   } /*locale_decode*/
255 
256 #if HAVE_ICONV && LOCALIZE_FILENAMES
257 
258 static iconv_t
259     to_locale = ICONV_NULL;
260 
localize_filename(const char * pathname)261 char * localize_filename(const char * pathname)
262   /* converts a filename from UTF-8 to localized encoding. */
263   {
264     char * result;
265     size_t inlen, outlen;
266     char * resultnext;
267     if (to_locale == ICONV_NULL)
268       {
269         fprintf(stderr, "INFO: Converting filenames to %s\n", default_charset);
270         to_locale = iconv_open(default_charset, "UTF-8");
271         if (to_locale == ICONV_NULL)
272           {
273             fprintf(stderr, "ERR:  Cannot convert from UTF-8 to charset \"%s\"\n", default_charset);
274             exit(1);
275           } /*if*/
276       } /*if*/
277     inlen = strlen(pathname);
278     outlen = inlen * 5; /* should be enough? */
279     result = malloc(outlen);
280     resultnext = result;
281     if (iconv(to_locale, (char **)&pathname, &inlen, &resultnext, &outlen) < 0)
282       {
283         fprintf
284           (
285             stderr,
286             "ERR:  Error %d -- %s encoding pathname \"%s\"\n",
287             errno, strerror(errno), pathname
288           );
289         exit(1);
290       } /*if*/
291     assert(outlen != 0); /* there will be room for ... */
292     *resultnext++ = 0; /* ... terminating null */
293     result = realloc(result, resultnext - result); /* free unneeded memory */
294     return result;
295   } /*localize_filename*/
296 
297 #endif
298 
299 /*
300     vfiles
301 */
302 
varied_open(const char * fname,int mode,const char * what)303 struct vfile varied_open
304   (
305     const char * fname,
306     int mode, /* either O_RDONLY or O_WRONLY, nothing more */
307     const char * what /* description of what I'm trying to open, for error message */
308   )
309   {
310     struct vfile vf;
311     int fnamelen;
312     if (strcmp(fname, "-") == 0)
313       {
314         vf.ftype = VFTYPE_REDIR;
315         vf.h = mode == O_RDONLY ? stdin : stdout;
316       }
317     else if (fname[0] == '&' && isdigit(fname[1]))
318       {
319         vf.ftype = VFTYPE_FILE;
320         vf.h = fdopen(atoi(fname + 1), mode == O_RDONLY ? "rb" : "wb");
321       }
322     else if (mode == O_WRONLY && fname[0] == '|')
323       {
324         vf.ftype = VFTYPE_PIPE;
325         vf.h = popen(fname + 1, "w");
326       }
327     else if (mode == O_RDONLY && fname[0] != '\0' && fname[fnamelen = strlen(fname) - 1] == '|')
328       {
329         char * const fcopy = strndup(fname, fnamelen);
330         vf.ftype = VFTYPE_PIPE;
331         vf.h = popen(fcopy, "r");
332         free(fcopy);
333       }
334     else
335       {
336         vf.ftype = VFTYPE_FILE;
337         vf.h = fopen(fname, mode == O_RDONLY ? "rb" : "wb");
338       } /*if*/
339     if (vf.h == NULL)
340       {
341         fprintf(stderr, "ERR:  %d opening %s \"%s\" -- %s\n", errno, what, fname, strerror(errno));
342         exit(1);
343       } /*if*/
344     vf.mode = mode;
345     return vf;
346   } /*varied_open*/
347 
varied_close(struct vfile vf)348 void varied_close(struct vfile vf)
349   {
350     if (vf.mode == O_WRONLY)
351       {
352       /* check for errors on final write before closing */
353         if (fflush(vf.h) != 0)
354           {
355             fprintf(stderr, "ERR:  %d on fflush -- %s\n", errno, strerror(errno));
356             exit(1);
357           } /*if*/
358       } /*if*/
359     switch (vf.ftype)
360       {
361     case VFTYPE_FILE:
362         fclose(vf.h);
363     break;
364     case VFTYPE_PIPE:
365         pclose(vf.h);
366     break;
367     case VFTYPE_REDIR:
368     default:
369       /* nothing to do */
370     break;
371       } /*switch*/
372   } /*varied_close*/
373 
374 /*
375     parsing of colour specs
376 */
377 
378 typedef struct
379   {
380     const char * name; /* null marks end of list */
381     colorspec color;
382   } named_color;
383 const static named_color predefined_color_names[] =
384   /* predefined colour names, copied from <http://www.imagemagick.org/script/color.php> */
385   {
386     {"snow", {255, 250, 250, 255}},
387     {"snow1", {255, 250, 250, 255}},
388     {"snow2", {238, 233, 233, 255}},
389     {"RosyBrown1", {255, 193, 193, 255}},
390     {"RosyBrown2", {238, 180, 180, 255}},
391     {"snow3", {205, 201, 201, 255}},
392     {"LightCoral", {240, 128, 128, 255}},
393     {"IndianRed1", {255, 106, 106, 255}},
394     {"RosyBrown3", {205, 155, 155, 255}},
395     {"IndianRed2", {238, 99, 99, 255}},
396     {"RosyBrown", {188, 143, 143, 255}},
397     {"brown1", {255, 64, 64, 255}},
398     {"firebrick1", {255, 48, 48, 255}},
399     {"brown2", {238, 59, 59, 255}},
400     {"IndianRed", {205, 92, 92, 255}},
401     {"IndianRed3", {205, 85, 85, 255}},
402     {"firebrick2", {238, 44, 44, 255}},
403     {"snow4", {139, 137, 137, 255}},
404     {"brown3", {205, 51, 51, 255}},
405     {"red", {255, 0, 0, 255}},
406     {"red1", {255, 0, 0, 255}},
407     {"RosyBrown4", {139, 105, 105, 255}},
408     {"firebrick3", {205, 38, 38, 255}},
409     {"red2", {238, 0, 0, 255}},
410     {"firebrick", {178, 34, 34, 255}},
411     {"brown", {165, 42, 42, 255}},
412     {"red3", {205, 0, 0, 255}},
413     {"IndianRed4", {139, 58, 58, 255}},
414     {"brown4", {139, 35, 35, 255}},
415     {"firebrick4", {139, 26, 26, 255}},
416     {"DarkRed", {139, 0, 0, 255}},
417     {"red4", {139, 0, 0, 255}},
418     {"maroon", {128, 0, 0, 255}},
419     {"LightPink1", {255, 174, 185, 255}},
420     {"LightPink3", {205, 140, 149, 255}},
421     {"LightPink4", {139, 95, 101, 255}},
422     {"LightPink2", {238, 162, 173, 255}},
423     {"LightPink", {255, 182, 193, 255}},
424     {"pink", {255, 192, 203, 255}},
425     {"crimson", {220, 20, 60, 255}},
426     {"pink1", {255, 181, 197, 255}},
427     {"pink2", {238, 169, 184, 255}},
428     {"pink3", {205, 145, 158, 255}},
429     {"pink4", {139, 99, 108, 255}},
430     {"PaleVioletRed4", {139, 71, 93, 255}},
431     {"PaleVioletRed", {219, 112, 147, 255}},
432     {"PaleVioletRed2", {238, 121, 159, 255}},
433     {"PaleVioletRed1", {255, 130, 171, 255}},
434     {"PaleVioletRed3", {205, 104, 137, 255}},
435     {"LavenderBlush", {255, 240, 245, 255}},
436     {"LavenderBlush1", {255, 240, 245, 255}},
437     {"LavenderBlush3", {205, 193, 197, 255}},
438     {"LavenderBlush2", {238, 224, 229, 255}},
439     {"LavenderBlush4", {139, 131, 134, 255}},
440     {"maroon", {176, 48, 96, 255}},
441     {"HotPink3", {205, 96, 144, 255}},
442     {"VioletRed3", {205, 50, 120, 255}},
443     {"VioletRed1", {255, 62, 150, 255}},
444     {"VioletRed2", {238, 58, 140, 255}},
445     {"VioletRed4", {139, 34, 82, 255}},
446     {"HotPink2", {238, 106, 167, 255}},
447     {"HotPink1", {255, 110, 180, 255}},
448     {"HotPink4", {139, 58, 98, 255}},
449     {"HotPink", {255, 105, 180, 255}},
450     {"DeepPink", {255, 20, 147, 255}},
451     {"DeepPink1", {255, 20, 147, 255}},
452     {"DeepPink2", {238, 18, 137, 255}},
453     {"DeepPink3", {205, 16, 118, 255}},
454     {"DeepPink4", {139, 10, 80, 255}},
455     {"maroon1", {255, 52, 179, 255}},
456     {"maroon2", {238, 48, 167, 255}},
457     {"maroon3", {205, 41, 144, 255}},
458     {"maroon4", {139, 28, 98, 255}},
459     {"MediumVioletRed", {199, 21, 133, 255}},
460     {"VioletRed", {208, 32, 144, 255}},
461     {"orchid2", {238, 122, 233, 255}},
462     {"orchid", {218, 112, 214, 255}},
463     {"orchid1", {255, 131, 250, 255}},
464     {"orchid3", {205, 105, 201, 255}},
465     {"orchid4", {139, 71, 137, 255}},
466     {"thistle1", {255, 225, 255, 255}},
467     {"thistle2", {238, 210, 238, 255}},
468     {"plum1", {255, 187, 255, 255}},
469     {"plum2", {238, 174, 238, 255}},
470     {"thistle", {216, 191, 216, 255}},
471     {"thistle3", {205, 181, 205, 255}},
472     {"plum", {221, 160, 221, 255}},
473     {"violet", {238, 130, 238, 255}},
474     {"plum3", {205, 150, 205, 255}},
475     {"thistle4", {139, 123, 139, 255}},
476     {"fuchsia", {255, 0, 255, 255}},
477     {"magenta", {255, 0, 255, 255}},
478     {"magenta1", {255, 0, 255, 255}},
479     {"plum4", {139, 102, 139, 255}},
480     {"magenta2", {238, 0, 238, 255}},
481     {"magenta3", {205, 0, 205, 255}},
482     {"DarkMagenta", {139, 0, 139, 255}},
483     {"magenta4", {139, 0, 139, 255}},
484     {"purple", {128, 0, 128, 255}},
485     {"MediumOrchid", {186, 85, 211, 255}},
486     {"MediumOrchid1", {224, 102, 255, 255}},
487     {"MediumOrchid2", {209, 95, 238, 255}},
488     {"MediumOrchid3", {180, 82, 205, 255}},
489     {"MediumOrchid4", {122, 55, 139, 255}},
490     {"DarkViolet", {148, 0, 211, 255}},
491     {"DarkOrchid", {153, 50, 204, 255}},
492     {"DarkOrchid1", {191, 62, 255, 255}},
493     {"DarkOrchid3", {154, 50, 205, 255}},
494     {"DarkOrchid2", {178, 58, 238, 255}},
495     {"DarkOrchid4", {104, 34, 139, 255}},
496     {"purple", {160, 32, 240, 255}},
497     {"indigo", { 75, 0, 130, 255}},
498     {"BlueViolet", {138, 43, 226, 255}},
499     {"purple2", {145, 44, 238, 255}},
500     {"purple3", {125, 38, 205, 255}},
501     {"purple4", { 85, 26, 139, 255}},
502     {"purple1", {155, 48, 255, 255}},
503     {"MediumPurple", {147, 112, 219, 255}},
504     {"MediumPurple1", {171, 130, 255, 255}},
505     {"MediumPurple2", {159, 121, 238, 255}},
506     {"MediumPurple3", {137, 104, 205, 255}},
507     {"MediumPurple4", { 93, 71, 139, 255}},
508     {"DarkSlateBlue", { 72, 61, 139, 255}},
509     {"LightSlateBlue", {132, 112, 255, 255}},
510     {"MediumSlateBlue", {123, 104, 238, 255}},
511     {"SlateBlue", {106, 90, 205, 255}},
512     {"SlateBlue1", {131, 111, 255, 255}},
513     {"SlateBlue2", {122, 103, 238, 255}},
514     {"SlateBlue3", {105, 89, 205, 255}},
515     {"SlateBlue4", { 71, 60, 139, 255}},
516     {"GhostWhite", {248, 248, 255, 255}},
517     {"lavender", {230, 230, 250, 255}},
518     {"blue", { 0, 0, 255, 255}},
519     {"blue1", { 0, 0, 255, 255}},
520     {"blue2", { 0, 0, 238, 255}},
521     {"blue3", { 0, 0, 205, 255}},
522     {"MediumBlue", { 0, 0, 205, 255}},
523     {"blue4", { 0, 0, 139, 255}},
524     {"DarkBlue", { 0, 0, 139, 255}},
525     {"MidnightBlue", { 25, 25, 112, 255}},
526     {"navy", { 0, 0, 128, 255}},
527     {"NavyBlue", { 0, 0, 128, 255}},
528     {"RoyalBlue", { 65, 105, 225, 255}},
529     {"RoyalBlue1", { 72, 118, 255, 255}},
530     {"RoyalBlue2", { 67, 110, 238, 255}},
531     {"RoyalBlue3", { 58, 95, 205, 255}},
532     {"RoyalBlue4", { 39, 64, 139, 255}},
533     {"CornflowerBlue", {100, 149, 237, 255}},
534     {"LightSteelBlue", {176, 196, 222, 255}},
535     {"LightSteelBlue1", {202, 225, 255, 255}},
536     {"LightSteelBlue2", {188, 210, 238, 255}},
537     {"LightSteelBlue3", {162, 181, 205, 255}},
538     {"LightSteelBlue4", {110, 123, 139, 255}},
539     {"SlateGray4", {108, 123, 139, 255}},
540     {"SlateGray1", {198, 226, 255, 255}},
541     {"SlateGray2", {185, 211, 238, 255}},
542     {"SlateGray3", {159, 182, 205, 255}},
543     {"LightSlateGray", {119, 136, 153, 255}},
544     {"LightSlateGrey", {119, 136, 153, 255}},
545     {"SlateGray", {112, 128, 144, 255}},
546     {"SlateGrey", {112, 128, 144, 255}},
547     {"DodgerBlue", { 30, 144, 255, 255}},
548     {"DodgerBlue1", { 30, 144, 255, 255}},
549     {"DodgerBlue2", { 28, 134, 238, 255}},
550     {"DodgerBlue4", { 16, 78, 139, 255}},
551     {"DodgerBlue3", { 24, 116, 205, 255}},
552     {"AliceBlue", {240, 248, 255, 255}},
553     {"SteelBlue4", { 54, 100, 139, 255}},
554     {"SteelBlue", { 70, 130, 180, 255}},
555     {"SteelBlue1", { 99, 184, 255, 255}},
556     {"SteelBlue2", { 92, 172, 238, 255}},
557     {"SteelBlue3", { 79, 148, 205, 255}},
558     {"SkyBlue4", { 74, 112, 139, 255}},
559     {"SkyBlue1", {135, 206, 255, 255}},
560     {"SkyBlue2", {126, 192, 238, 255}},
561     {"SkyBlue3", {108, 166, 205, 255}},
562     {"LightSkyBlue", {135, 206, 250, 255}},
563     {"LightSkyBlue4", { 96, 123, 139, 255}},
564     {"LightSkyBlue1", {176, 226, 255, 255}},
565     {"LightSkyBlue2", {164, 211, 238, 255}},
566     {"LightSkyBlue3", {141, 182, 205, 255}},
567     {"SkyBlue", {135, 206, 235, 255}},
568     {"LightBlue3", {154, 192, 205, 255}},
569     {"DeepSkyBlue", { 0, 191, 255, 255}},
570     {"DeepSkyBlue1", { 0, 191, 255, 255}},
571     {"DeepSkyBlue2", { 0, 178, 238, 255}},
572     {"DeepSkyBlue4", { 0, 104, 139, 255}},
573     {"DeepSkyBlue3", { 0, 154, 205, 255}},
574     {"LightBlue1", {191, 239, 255, 255}},
575     {"LightBlue2", {178, 223, 238, 255}},
576     {"LightBlue", {173, 216, 230, 255}},
577     {"LightBlue4", {104, 131, 139, 255}},
578     {"PowderBlue", {176, 224, 230, 255}},
579     {"CadetBlue1", {152, 245, 255, 255}},
580     {"CadetBlue2", {142, 229, 238, 255}},
581     {"CadetBlue3", {122, 197, 205, 255}},
582     {"CadetBlue4", { 83, 134, 139, 255}},
583     {"turquoise1", { 0, 245, 255, 255}},
584     {"turquoise2", { 0, 229, 238, 255}},
585     {"turquoise3", { 0, 197, 205, 255}},
586     {"turquoise4", { 0, 134, 139, 255}},
587   /* {"cadet blue", { 95, 158, 160, 255}}, */ /* don't allow space in name */
588     {"CadetBlue", { 95, 158, 160, 255}},
589     {"DarkTurquoise", { 0, 206, 209, 255}},
590     {"azure", {240, 255, 255, 255}},
591     {"azure1", {240, 255, 255, 255}},
592     {"LightCyan", {224, 255, 255, 255}},
593     {"LightCyan1", {224, 255, 255, 255}},
594     {"azure2", {224, 238, 238, 255}},
595     {"LightCyan2", {209, 238, 238, 255}},
596     {"PaleTurquoise1", {187, 255, 255, 255}},
597     {"PaleTurquoise", {175, 238, 238, 255}},
598     {"PaleTurquoise2", {174, 238, 238, 255}},
599     {"DarkSlateGray1", {151, 255, 255, 255}},
600     {"azure3", {193, 205, 205, 255}},
601     {"LightCyan3", {180, 205, 205, 255}},
602     {"DarkSlateGray2", {141, 238, 238, 255}},
603     {"PaleTurquoise3", {150, 205, 205, 255}},
604     {"DarkSlateGray3", {121, 205, 205, 255}},
605     {"azure4", {131, 139, 139, 255}},
606     {"LightCyan4", {122, 139, 139, 255}},
607     {"aqua", { 0, 255, 255, 255}},
608     {"cyan", { 0, 255, 255, 255}},
609     {"cyan1", { 0, 255, 255, 255}},
610     {"PaleTurquoise4", {102, 139, 139, 255}},
611     {"cyan2", { 0, 238, 238, 255}},
612     {"DarkSlateGray4", { 82, 139, 139, 255}},
613     {"cyan3", { 0, 205, 205, 255}},
614     {"cyan4", { 0, 139, 139, 255}},
615     {"DarkCyan", { 0, 139, 139, 255}},
616     {"teal", { 0, 128, 128, 255}},
617     {"DarkSlateGray", { 47, 79, 79, 255}},
618     {"DarkSlateGrey", { 47, 79, 79, 255}},
619     {"MediumTurquoise", { 72, 209, 204, 255}},
620     {"LightSeaGreen", { 32, 178, 170, 255}},
621     {"turquoise", { 64, 224, 208, 255}},
622     {"aquamarine4", { 69, 139, 116, 255}},
623     {"aquamarine", {127, 255, 212, 255}},
624     {"aquamarine1", {127, 255, 212, 255}},
625     {"aquamarine2", {118, 238, 198, 255}},
626     {"aquamarine3", {102, 205, 170, 255}},
627     {"MediumAquamarine", {102, 205, 170, 255}},
628     {"MediumSpringGreen", { 0, 250, 154, 255}},
629     {"MintCream", {245, 255, 250, 255}},
630     {"SpringGreen", { 0, 255, 127, 255}},
631     {"SpringGreen1", { 0, 255, 127, 255}},
632     {"SpringGreen2", { 0, 238, 118, 255}},
633     {"SpringGreen3", { 0, 205, 102, 255}},
634     {"SpringGreen4", { 0, 139, 69, 255}},
635     {"MediumSeaGreen", { 60, 179, 113, 255}},
636     {"SeaGreen", { 46, 139, 87, 255}},
637     {"SeaGreen3", { 67, 205, 128, 255}},
638     {"SeaGreen1", { 84, 255, 159, 255}},
639     {"SeaGreen4", { 46, 139, 87, 255}},
640     {"SeaGreen2", { 78, 238, 148, 255}},
641     {"MediumForestGreen", { 50, 129, 75, 255}},
642     {"honeydew", {240, 255, 240, 255}},
643     {"honeydew1", {240, 255, 240, 255}},
644     {"honeydew2", {224, 238, 224, 255}},
645     {"DarkSeaGreen1", {193, 255, 193, 255}},
646     {"DarkSeaGreen2", {180, 238, 180, 255}},
647     {"PaleGreen1", {154, 255, 154, 255}},
648     {"PaleGreen", {152, 251, 152, 255}},
649     {"honeydew3", {193, 205, 193, 255}},
650     {"LightGreen", {144, 238, 144, 255}},
651     {"PaleGreen2", {144, 238, 144, 255}},
652     {"DarkSeaGreen3", {155, 205, 155, 255}},
653     {"DarkSeaGreen", {143, 188, 143, 255}},
654     {"PaleGreen3", {124, 205, 124, 255}},
655     {"honeydew4", {131, 139, 131, 255}},
656     {"green1", { 0, 255, 0, 255}},
657     {"lime", { 0, 255, 0, 255}},
658     {"LimeGreen", { 50, 205, 50, 255}},
659     {"DarkSeaGreen4", {105, 139, 105, 255}},
660     {"green2", { 0, 238, 0, 255}},
661     {"PaleGreen4", { 84, 139, 84, 255}},
662     {"green3", { 0, 205, 0, 255}},
663     {"ForestGreen", { 34, 139, 34, 255}},
664     {"green4", { 0, 139, 0, 255}},
665     {"green", { 0, 128, 0, 255}},
666     {"DarkGreen", { 0, 100, 0, 255}},
667     {"LawnGreen", {124, 252, 0, 255}},
668     {"chartreuse", {127, 255, 0, 255}},
669     {"chartreuse1", {127, 255, 0, 255}},
670     {"chartreuse2", {118, 238, 0, 255}},
671     {"chartreuse3", {102, 205, 0, 255}},
672     {"chartreuse4", { 69, 139, 0, 255}},
673     {"GreenYellow", {173, 255, 47, 255}},
674     {"DarkOliveGreen3", {162, 205, 90, 255}},
675     {"DarkOliveGreen1", {202, 255, 112, 255}},
676     {"DarkOliveGreen2", {188, 238, 104, 255}},
677     {"DarkOliveGreen4", {110, 139, 61, 255}},
678     {"DarkOliveGreen", { 85, 107, 47, 255}},
679     {"OliveDrab", {107, 142, 35, 255}},
680     {"OliveDrab1", {192, 255, 62, 255}},
681     {"OliveDrab2", {179, 238, 58, 255}},
682     {"OliveDrab3", {154, 205, 50, 255}},
683     {"YellowGreen", {154, 205, 50, 255}},
684     {"OliveDrab4", {105, 139, 34, 255}},
685     {"ivory", {255, 255, 240, 255}},
686     {"ivory1", {255, 255, 240, 255}},
687     {"LightYellow", {255, 255, 224, 255}},
688     {"LightYellow1", {255, 255, 224, 255}},
689     {"beige", {245, 245, 220, 255}},
690     {"ivory2", {238, 238, 224, 255}},
691     {"LightGoldenrodYellow", {250, 250, 210, 255}},
692     {"LightYellow2", {238, 238, 209, 255}},
693     {"ivory3", {205, 205, 193, 255}},
694     {"LightYellow3", {205, 205, 180, 255}},
695     {"ivory4", {139, 139, 131, 255}},
696     {"LightYellow4", {139, 139, 122, 255}},
697     {"yellow", {255, 255, 0, 255}},
698     {"yellow1", {255, 255, 0, 255}},
699     {"yellow2", {238, 238, 0, 255}},
700     {"yellow3", {205, 205, 0, 255}},
701     {"yellow4", {139, 139, 0, 255}},
702     {"olive", {128, 128, 0, 255}},
703     {"DarkKhaki", {189, 183, 107, 255}},
704     {"khaki2", {238, 230, 133, 255}},
705     {"LemonChiffon4", {139, 137, 112, 255}},
706     {"khaki1", {255, 246, 143, 255}},
707     {"khaki3", {205, 198, 115, 255}},
708     {"khaki4", {139, 134, 78, 255}},
709     {"PaleGoldenrod", {238, 232, 170, 255}},
710     {"LemonChiffon", {255, 250, 205, 255}},
711     {"LemonChiffon1", {255, 250, 205, 255}},
712     {"khaki", {240, 230, 140, 255}},
713     {"LemonChiffon3", {205, 201, 165, 255}},
714     {"LemonChiffon2", {238, 233, 191, 255}},
715     {"MediumGoldenRod", {209, 193, 102, 255}},
716     {"cornsilk4", {139, 136, 120, 255}},
717     {"gold", {255, 215, 0, 255}},
718     {"gold1", {255, 215, 0, 255}},
719     {"gold2", {238, 201, 0, 255}},
720     {"gold3", {205, 173, 0, 255}},
721     {"gold4", {139, 117, 0, 255}},
722     {"LightGoldenrod", {238, 221, 130, 255}},
723     {"LightGoldenrod4", {139, 129, 76, 255}},
724     {"LightGoldenrod1", {255, 236, 139, 255}},
725     {"LightGoldenrod3", {205, 190, 112, 255}},
726     {"LightGoldenrod2", {238, 220, 130, 255}},
727     {"cornsilk3", {205, 200, 177, 255}},
728     {"cornsilk2", {238, 232, 205, 255}},
729     {"cornsilk", {255, 248, 220, 255}},
730     {"cornsilk1", {255, 248, 220, 255}},
731     {"goldenrod", {218, 165, 32, 255}},
732     {"goldenrod1", {255, 193, 37, 255}},
733     {"goldenrod2", {238, 180, 34, 255}},
734     {"goldenrod3", {205, 155, 29, 255}},
735     {"goldenrod4", {139, 105, 20, 255}},
736     {"DarkGoldenrod", {184, 134, 11, 255}},
737     {"DarkGoldenrod1", {255, 185, 15, 255}},
738     {"DarkGoldenrod2", {238, 173, 14, 255}},
739     {"DarkGoldenrod3", {205, 149, 12, 255}},
740     {"DarkGoldenrod4", {139, 101, 8, 255}},
741     {"FloralWhite", {255, 250, 240, 255}},
742     {"wheat2", {238, 216, 174, 255}},
743     {"OldLace", {253, 245, 230, 255}},
744     {"wheat", {245, 222, 179, 255}},
745     {"wheat1", {255, 231, 186, 255}},
746     {"wheat3", {205, 186, 150, 255}},
747     {"orange", {255, 165, 0, 255}},
748     {"orange1", {255, 165, 0, 255}},
749     {"orange2", {238, 154, 0, 255}},
750     {"orange3", {205, 133, 0, 255}},
751     {"orange4", {139, 90, 0, 255}},
752     {"wheat4", {139, 126, 102, 255}},
753     {"moccasin", {255, 228, 181, 255}},
754     {"PapayaWhip", {255, 239, 213, 255}},
755     {"NavajoWhite3", {205, 179, 139, 255}},
756     {"BlanchedAlmond", {255, 235, 205, 255}},
757     {"NavajoWhite", {255, 222, 173, 255}},
758     {"NavajoWhite1", {255, 222, 173, 255}},
759     {"NavajoWhite2", {238, 207, 161, 255}},
760     {"NavajoWhite4", {139, 121, 94, 255}},
761     {"AntiqueWhite4", {139, 131, 120, 255}},
762     {"AntiqueWhite", {250, 235, 215, 255}},
763     {"tan", {210, 180, 140, 255}},
764     {"bisque4", {139, 125, 107, 255}},
765     {"burlywood", {222, 184, 135, 255}},
766     {"AntiqueWhite2", {238, 223, 204, 255}},
767     {"burlywood1", {255, 211, 155, 255}},
768     {"burlywood3", {205, 170, 125, 255}},
769     {"burlywood2", {238, 197, 145, 255}},
770     {"AntiqueWhite1", {255, 239, 219, 255}},
771     {"burlywood4", {139, 115, 85, 255}},
772     {"AntiqueWhite3", {205, 192, 176, 255}},
773     {"DarkOrange", {255, 140, 0, 255}},
774     {"bisque2", {238, 213, 183, 255}},
775     {"bisque", {255, 228, 196, 255}},
776     {"bisque1", {255, 228, 196, 255}},
777     {"bisque3", {205, 183, 158, 255}},
778     {"DarkOrange1", {255, 127, 0, 255}},
779     {"linen", {250, 240, 230, 255}},
780     {"DarkOrange2", {238, 118, 0, 255}},
781     {"DarkOrange3", {205, 102, 0, 255}},
782     {"DarkOrange4", {139, 69, 0, 255}},
783     {"peru", {205, 133, 63, 255}},
784     {"tan1", {255, 165, 79, 255}},
785     {"tan2", {238, 154, 73, 255}},
786     {"tan3", {205, 133, 63, 255}},
787     {"tan4", {139, 90, 43, 255}},
788     {"PeachPuff", {255, 218, 185, 255}},
789     {"PeachPuff1", {255, 218, 185, 255}},
790     {"PeachPuff4", {139, 119, 101, 255}},
791     {"PeachPuff2", {238, 203, 173, 255}},
792     {"PeachPuff3", {205, 175, 149, 255}},
793     {"SandyBrown", {244, 164, 96, 255}},
794     {"seashell4", {139, 134, 130, 255}},
795     {"seashell2", {238, 229, 222, 255}},
796     {"seashell3", {205, 197, 191, 255}},
797     {"chocolate", {210, 105, 30, 255}},
798     {"chocolate1", {255, 127, 36, 255}},
799     {"chocolate2", {238, 118, 33, 255}},
800     {"chocolate3", {205, 102, 29, 255}},
801     {"chocolate4", {139, 69, 19, 255}},
802     {"SaddleBrown", {139, 69, 19, 255}},
803     {"seashell", {255, 245, 238, 255}},
804     {"seashell1", {255, 245, 238, 255}},
805     {"sienna4", {139, 71, 38, 255}},
806     {"sienna", {160, 82, 45, 255}},
807     {"sienna1", {255, 130, 71, 255}},
808     {"sienna2", {238, 121, 66, 255}},
809     {"sienna3", {205, 104, 57, 255}},
810     {"LightSalmon3", {205, 129, 98, 255}},
811     {"LightSalmon", {255, 160, 122, 255}},
812     {"LightSalmon1", {255, 160, 122, 255}},
813     {"LightSalmon4", {139, 87, 66, 255}},
814     {"LightSalmon2", {238, 149, 114, 255}},
815     {"coral", {255, 127, 80, 255}},
816     {"OrangeRed", {255, 69, 0, 255}},
817     {"OrangeRed1", {255, 69, 0, 255}},
818     {"OrangeRed2", {238, 64, 0, 255}},
819     {"OrangeRed3", {205, 55, 0, 255}},
820     {"OrangeRed4", {139, 37, 0, 255}},
821     {"DarkSalmon", {233, 150, 122, 255}},
822     {"salmon1", {255, 140, 105, 255}},
823     {"salmon2", {238, 130, 98, 255}},
824     {"salmon3", {205, 112, 84, 255}},
825     {"salmon4", {139, 76, 57, 255}},
826     {"coral1", {255, 114, 86, 255}},
827     {"coral2", {238, 106, 80, 255}},
828     {"coral3", {205, 91, 69, 255}},
829     {"coral4", {139, 62, 47, 255}},
830     {"tomato4", {139, 54, 38, 255}},
831     {"tomato", {255, 99, 71, 255}},
832     {"tomato1", {255, 99, 71, 255}},
833     {"tomato2", {238, 92, 66, 255}},
834     {"tomato3", {205, 79, 57, 255}},
835     {"MistyRose4", {139, 125, 123, 255}},
836     {"MistyRose2", {238, 213, 210, 255}},
837     {"MistyRose", {255, 228, 225, 255}},
838     {"MistyRose1", {255, 228, 225, 255}},
839     {"salmon", {250, 128, 114, 255}},
840     {"MistyRose3", {205, 183, 181, 255}},
841     {"white", {255, 255, 255, 255}},
842     {"gray100", {255, 255, 255, 255}},
843     {"grey100", {255, 255, 255, 255}},
844     {"grey100", {255, 255, 255, 255}},
845     {"gray99", {252, 252, 252, 255}},
846     {"grey99", {252, 252, 252, 255}},
847     {"gray98", {250, 250, 250, 255}},
848     {"grey98", {250, 250, 250, 255}},
849     {"gray97", {247, 247, 247, 255}},
850     {"grey97", {247, 247, 247, 255}},
851     {"gray96", {245, 245, 245, 255}},
852     {"grey96", {245, 245, 245, 255}},
853     {"WhiteSmoke", {245, 245, 245, 255}},
854     {"gray95", {242, 242, 242, 255}},
855     {"grey95", {242, 242, 242, 255}},
856     {"gray94", {240, 240, 240, 255}},
857     {"grey94", {240, 240, 240, 255}},
858     {"gray93", {237, 237, 237, 255}},
859     {"grey93", {237, 237, 237, 255}},
860     {"gray92", {235, 235, 235, 255}},
861     {"grey92", {235, 235, 235, 255}},
862     {"gray91", {232, 232, 232, 255}},
863     {"grey91", {232, 232, 232, 255}},
864     {"gray90", {229, 229, 229, 255}},
865     {"grey90", {229, 229, 229, 255}},
866     {"gray89", {227, 227, 227, 255}},
867     {"grey89", {227, 227, 227, 255}},
868     {"gray88", {224, 224, 224, 255}},
869     {"grey88", {224, 224, 224, 255}},
870     {"gray87", {222, 222, 222, 255}},
871     {"grey87", {222, 222, 222, 255}},
872     {"gainsboro", {220, 220, 220, 255}},
873     {"gray86", {219, 219, 219, 255}},
874     {"grey86", {219, 219, 219, 255}},
875     {"gray85", {217, 217, 217, 255}},
876     {"grey85", {217, 217, 217, 255}},
877     {"gray84", {214, 214, 214, 255}},
878     {"grey84", {214, 214, 214, 255}},
879     {"gray83", {212, 212, 212, 255}},
880     {"grey83", {212, 212, 212, 255}},
881     {"LightGray", {211, 211, 211, 255}},
882     {"LightGrey", {211, 211, 211, 255}},
883     {"gray82", {209, 209, 209, 255}},
884     {"grey82", {209, 209, 209, 255}},
885     {"gray81", {207, 207, 207, 255}},
886     {"grey81", {207, 207, 207, 255}},
887     {"gray80", {204, 204, 204, 255}},
888     {"grey80", {204, 204, 204, 255}},
889     {"gray79", {201, 201, 201, 255}},
890     {"grey79", {201, 201, 201, 255}},
891     {"gray78", {199, 199, 199, 255}},
892     {"grey78", {199, 199, 199, 255}},
893     {"gray77", {196, 196, 196, 255}},
894     {"grey77", {196, 196, 196, 255}},
895     {"gray76", {194, 194, 194, 255}},
896     {"grey76", {194, 194, 194, 255}},
897     {"silver", {192, 192, 192, 255}},
898     {"gray75", {191, 191, 191, 255}},
899     {"grey75", {191, 191, 191, 255}},
900     {"gray74", {189, 189, 189, 255}},
901     {"grey74", {189, 189, 189, 255}},
902     {"gray73", {186, 186, 186, 255}},
903     {"grey73", {186, 186, 186, 255}},
904     {"gray72", {184, 184, 184, 255}},
905     {"grey72", {184, 184, 184, 255}},
906     {"gray71", {181, 181, 181, 255}},
907     {"grey71", {181, 181, 181, 255}},
908     {"gray70", {179, 179, 179, 255}},
909     {"grey70", {179, 179, 179, 255}},
910     {"gray69", {176, 176, 176, 255}},
911     {"grey69", {176, 176, 176, 255}},
912     {"gray68", {173, 173, 173, 255}},
913     {"grey68", {173, 173, 173, 255}},
914     {"gray67", {171, 171, 171, 255}},
915     {"grey67", {171, 171, 171, 255}},
916     {"DarkGray", {169, 169, 169, 255}},
917     {"DarkGrey", {169, 169, 169, 255}},
918     {"gray66", {168, 168, 168, 255}},
919     {"grey66", {168, 168, 168, 255}},
920     {"gray65", {166, 166, 166, 255}},
921     {"grey65", {166, 166, 166, 255}},
922     {"gray64", {163, 163, 163, 255}},
923     {"grey64", {163, 163, 163, 255}},
924     {"gray63", {161, 161, 161, 255}},
925     {"grey63", {161, 161, 161, 255}},
926     {"gray62", {158, 158, 158, 255}},
927     {"grey62", {158, 158, 158, 255}},
928     {"gray61", {156, 156, 156, 255}},
929     {"grey61", {156, 156, 156, 255}},
930     {"gray60", {153, 153, 153, 255}},
931     {"grey60", {153, 153, 153, 255}},
932     {"gray59", {150, 150, 150, 255}},
933     {"grey59", {150, 150, 150, 255}},
934     {"gray58", {148, 148, 148, 255}},
935     {"grey58", {148, 148, 148, 255}},
936     {"gray57", {145, 145, 145, 255}},
937     {"grey57", {145, 145, 145, 255}},
938     {"gray56", {143, 143, 143, 255}},
939     {"grey56", {143, 143, 143, 255}},
940     {"gray55", {140, 140, 140, 255}},
941     {"grey55", {140, 140, 140, 255}},
942     {"gray54", {138, 138, 138, 255}},
943     {"grey54", {138, 138, 138, 255}},
944     {"gray53", {135, 135, 135, 255}},
945     {"grey53", {135, 135, 135, 255}},
946     {"gray52", {133, 133, 133, 255}},
947     {"grey52", {133, 133, 133, 255}},
948     {"gray51", {130, 130, 130, 255}},
949     {"grey51", {130, 130, 130, 255}},
950     {"fractal", {128, 128, 128, 255}},
951     {"gray50", {127, 127, 127, 255}},
952     {"grey50", {127, 127, 127, 255}},
953     {"gray", {126, 126, 126, 255}},
954     {"gray49", {125, 125, 125, 255}},
955     {"grey49", {125, 125, 125, 255}},
956     {"gray48", {122, 122, 122, 255}},
957     {"grey48", {122, 122, 122, 255}},
958     {"gray47", {120, 120, 120, 255}},
959     {"grey47", {120, 120, 120, 255}},
960     {"gray46", {117, 117, 117, 255}},
961     {"grey46", {117, 117, 117, 255}},
962     {"gray45", {115, 115, 115, 255}},
963     {"grey45", {115, 115, 115, 255}},
964     {"gray44", {112, 112, 112, 255}},
965     {"grey44", {112, 112, 112, 255}},
966     {"gray43", {110, 110, 110, 255}},
967     {"grey43", {110, 110, 110, 255}},
968     {"gray42", {107, 107, 107, 255}},
969     {"grey42", {107, 107, 107, 255}},
970     {"DimGray", {105, 105, 105, 255}},
971     {"DimGrey", {105, 105, 105, 255}},
972     {"gray41", {105, 105, 105, 255}},
973     {"grey41", {105, 105, 105, 255}},
974     {"gray40", {102, 102, 102, 255}},
975     {"grey40", {102, 102, 102, 255}},
976     {"gray39", { 99, 99, 99, 255}},
977     {"grey39", { 99, 99, 99, 255}},
978     {"gray38", { 97, 97, 97, 255}},
979     {"grey38", { 97, 97, 97, 255}},
980     {"gray37", { 94, 94, 94, 255}},
981     {"grey37", { 94, 94, 94, 255}},
982     {"gray36", { 92, 92, 92, 255}},
983     {"grey36", { 92, 92, 92, 255}},
984     {"gray35", { 89, 89, 89, 255}},
985     {"grey35", { 89, 89, 89, 255}},
986     {"gray34", { 87, 87, 87, 255}},
987     {"grey34", { 87, 87, 87, 255}},
988     {"gray33", { 84, 84, 84, 255}},
989     {"grey33", { 84, 84, 84, 255}},
990     {"gray32", { 82, 82, 82, 255}},
991     {"grey32", { 82, 82, 82, 255}},
992     {"gray31", { 79, 79, 79, 255}},
993     {"grey31", { 79, 79, 79, 255}},
994     {"gray30", { 77, 77, 77, 255}},
995     {"grey30", { 77, 77, 77, 255}},
996     {"gray29", { 74, 74, 74, 255}},
997     {"grey29", { 74, 74, 74, 255}},
998     {"gray28", { 71, 71, 71, 255}},
999     {"grey28", { 71, 71, 71, 255}},
1000     {"gray27", { 69, 69, 69, 255}},
1001     {"grey27", { 69, 69, 69, 255}},
1002     {"gray26", { 66, 66, 66, 255}},
1003     {"grey26", { 66, 66, 66, 255}},
1004     {"gray25", { 64, 64, 64, 255}},
1005     {"grey25", { 64, 64, 64, 255}},
1006     {"gray24", { 61, 61, 61, 255}},
1007     {"grey24", { 61, 61, 61, 255}},
1008     {"gray23", { 59, 59, 59, 255}},
1009     {"grey23", { 59, 59, 59, 255}},
1010     {"gray22", { 56, 56, 56, 255}},
1011     {"grey22", { 56, 56, 56, 255}},
1012     {"gray21", { 54, 54, 54, 255}},
1013     {"grey21", { 54, 54, 54, 255}},
1014     {"gray20", { 51, 51, 51, 255}},
1015     {"grey20", { 51, 51, 51, 255}},
1016     {"gray19", { 48, 48, 48, 255}},
1017     {"grey19", { 48, 48, 48, 255}},
1018     {"gray18", { 46, 46, 46, 255}},
1019     {"grey18", { 46, 46, 46, 255}},
1020     {"gray17", { 43, 43, 43, 255}},
1021     {"grey17", { 43, 43, 43, 255}},
1022     {"gray16", { 41, 41, 41, 255}},
1023     {"grey16", { 41, 41, 41, 255}},
1024     {"gray15", { 38, 38, 38, 255}},
1025     {"grey15", { 38, 38, 38, 255}},
1026     {"gray14", { 36, 36, 36, 255}},
1027     {"grey14", { 36, 36, 36, 255}},
1028     {"gray13", { 33, 33, 33, 255}},
1029     {"grey13", { 33, 33, 33, 255}},
1030     {"gray12", { 31, 31, 31, 255}},
1031     {"grey12", { 31, 31, 31, 255}},
1032     {"gray11", { 28, 28, 28, 255}},
1033     {"grey11", { 28, 28, 28, 255}},
1034     {"gray10", { 26, 26, 26, 255}},
1035     {"grey10", { 26, 26, 26, 255}},
1036     {"gray9", { 23, 23, 23, 255}},
1037     {"grey9", { 23, 23, 23, 255}},
1038     {"gray8", { 20, 20, 20, 255}},
1039     {"grey8", { 20, 20, 20, 255}},
1040     {"gray7", { 18, 18, 18, 255}},
1041     {"grey7", { 18, 18, 18, 255}},
1042     {"gray6", { 15, 15, 15, 255}},
1043     {"grey6", { 15, 15, 15, 255}},
1044     {"gray5", { 13, 13, 13, 255}},
1045     {"grey5", { 13, 13, 13, 255}},
1046     {"gray4", { 10, 10, 10, 255}},
1047     {"grey4", { 10, 10, 10, 255}},
1048     {"gray3", { 8, 8, 8, 255}},
1049     {"grey3", { 8, 8, 8, 255}},
1050     {"gray2", { 5, 5, 5, 255}},
1051     {"grey2", { 5, 5, 5, 255}},
1052     {"gray1", { 3, 3, 3, 255}},
1053     {"grey1", { 3, 3, 3, 255}},
1054     {"black", { 0, 0, 0, 255}},
1055     {"gray0", { 0, 0, 0, 255}},
1056     {"grey0", { 0, 0, 0, 255}},
1057     {"opaque", { 0, 0, 0, 255}},
1058     {"none", { 0, 0, 0, 0}},
1059     {"transparent", {0, 0, 0, 0}},
1060     {0, {0, 0, 0, 0}} /* marks end of list */
1061   };
1062 
skipseparators(const char ** src,const char * srcend)1063 static void skipseparators
1064   (
1065     const char ** src,
1066     const char * srcend
1067   )
1068   {
1069     unsigned char ch;
1070     for (;;)
1071       {
1072         if (*src == srcend)
1073             break;
1074        ch = **src;
1075        if (ch != ' ' && ch != '\n' && ch != '\t')
1076            break;
1077        ++*src;
1078       } /*for*/
1079   } /*skipseparators*/
1080 
parse_color_component(const char ** src,const char * srcend,int maxvalue,int * value)1081 static bool parse_color_component
1082   (
1083     const char ** src,
1084     const char * srcend,
1085     int maxvalue,
1086     int * value
1087   )
1088   /* parses a colour component which can be a number [0 .. maxvalue]
1089     or a percentage of maxvalue. */
1090   {
1091     bool ok;
1092     float fvalue;
1093     int factor;
1094     bool decptseen, percentseen;
1095     unsigned char ch;
1096     decptseen = false;
1097     percentseen = false;
1098     fvalue = 0;
1099     do /*once*/
1100       {
1101         ok = false; /* in case no valid characters seen */
1102         for (;;)
1103           {
1104             if (*src == srcend)
1105                 break;
1106             ch = **src;
1107             ++*src;
1108             ok = true; /* if not already set */
1109             if (ch >= '0' && ch <= '9')
1110               {
1111                 const int val = ch - '0';
1112                 if (decptseen)
1113                   {
1114                     fvalue += (float)val / factor;
1115                     factor *= 10;
1116                   }
1117                 else
1118                   {
1119                     fvalue = fvalue * 10 + val;
1120                   } /*if*/
1121               }
1122             else if (ch == '.')
1123               {
1124                 if (decptseen)
1125                   {
1126                     ok = false;
1127                     break;
1128                   } /*if*/
1129                 decptseen = true;
1130                 factor = 10;
1131               }
1132             else if (ch == '%')
1133               {
1134                 percentseen = true;
1135                 break;
1136               }
1137             else
1138               {
1139                 --*src;
1140                 break;
1141               } /*if*/
1142           } /*for*/
1143         if (!ok)
1144             break;
1145         if (fvalue > (percentseen ? 100 : maxvalue))
1146           {
1147             ok = false;
1148             break;
1149           } /*if*/
1150         *value = percentseen ? fvalue * maxvalue / 100 : fvalue;
1151       }
1152     while (false);
1153     return ok;
1154   } /*parse_color_component*/
1155 
parse_color(const char * colorstr,const char * what)1156 colorspec parse_color
1157   (
1158     const char * colorstr,
1159     const char * what /* additional explanatory text for error message */
1160   )
1161   /* parses colorstr and returns the resulting colour. Will abort the process
1162     on any errors. */
1163   {
1164     colorspec result;
1165     const char * src;
1166     const char * const srcend = colorstr + strlen(colorstr);
1167     const char * errmsg = 0;
1168     char c;
1169     int colorindex;
1170     bool hex, nonhex, paren;
1171     do /*once*/
1172       {
1173         hex = false;
1174         nonhex = false;
1175         paren = false;
1176         src = colorstr;
1177         for (;;)
1178           {
1179             if (src == srcend)
1180                 break;
1181             c = *src;
1182             if (c == '#')
1183               {
1184                 if (src != colorstr) /* must occur at start */
1185                   {
1186                     errmsg = "illegal \"#\"";
1187                     break;
1188                   } /*if*/
1189                 hex = true;
1190               }
1191             else if (c == '(')
1192               {
1193                 paren = true;
1194                 break;
1195               }
1196             else if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c >= 'A' && c <= 'Z')
1197               {
1198                 if (c > 'f' && c <= 'z' || c > 'F' && c <= 'Z')
1199                   {
1200                     nonhex = true;
1201                   } /*if*/
1202               }
1203             else
1204               {
1205                 errmsg = "non-alphanumeric character";
1206                 break;
1207               } /*if*/
1208             ++src;
1209           } /*for*/
1210         if (errmsg != 0)
1211             break;
1212         if (hex && (nonhex || paren))
1213           {
1214             errmsg = "doesn't make sense";
1215             break;
1216           } /*if*/
1217         if (paren)
1218           {
1219             enum
1220               {
1221                 maxspacename = 5, /* max length of all the valid colour space names */
1222               };
1223             char spacename[maxspacename + 1];
1224             int nrcomponents, componentindex, component[4];
1225             bool gotcolors, gothue, gotlightness, gotalpha;
1226             if (src - colorstr > maxspacename)
1227               {
1228                 errmsg = "illegal color-space name";
1229                 break;
1230               } /*if*/
1231             memcpy(spacename, colorstr, src - colorstr);
1232             spacename[src - colorstr] = 0;
1233             if (strcasecmp(spacename, "rgb") == 0)
1234               {
1235                 nrcomponents = 3;
1236                 gotcolors = true;
1237                 gothue = false;
1238                 gotalpha = false;
1239               }
1240             else if (strcasecmp(spacename, "rgba") == 0)
1241               {
1242                 nrcomponents = 4;
1243                 gotcolors = true;
1244                 gothue = false;
1245                 gotalpha = true;
1246               }
1247             else if (strcasecmp(spacename, "gray") == 0)
1248               {
1249                 nrcomponents = 1;
1250                 gotcolors = false;
1251                 gothue = false;
1252                 gotalpha = false;
1253               }
1254             else if (strcasecmp(spacename, "graya") == 0)
1255               {
1256                 nrcomponents = 2;
1257                 gotcolors = false;
1258                 gothue = false;
1259                 gotalpha = true;
1260               }
1261             else if (strcasecmp(spacename, "hsb") == 0 || strcasecmp(spacename, "hsv") == 0)
1262               {
1263                 nrcomponents = 3;
1264                 gotcolors = true;
1265                 gothue = true;
1266                 gotlightness = false;
1267                 gotalpha = false;
1268               }
1269             else if (strcasecmp(spacename, "hsba") == 0 || strcasecmp(spacename, "hsva") == 0)
1270               {
1271                 nrcomponents = 4;
1272                 gotcolors = true;
1273                 gothue = true;
1274                 gotlightness = false;
1275                 gotalpha = true;
1276               }
1277             else if (strcasecmp(spacename, "hsl") == 0)
1278               {
1279                 nrcomponents = 3;
1280                 gotcolors = true;
1281                 gothue = true;
1282                 gotlightness = true;
1283                 gotalpha = false;
1284               }
1285             else if (strcasecmp(spacename, "hsla") == 0)
1286               {
1287                 nrcomponents = 4;
1288                 gotcolors = true;
1289                 gothue = true;
1290                 gotlightness = true;
1291                 gotalpha = true;
1292               }
1293             else
1294               {
1295                 errmsg = "can't recognize color-space name";
1296                 break;
1297               } /*if*/
1298             for (componentindex = 0;;)
1299               {
1300                 if (componentindex == 0 ? *src != '(' : *src != ',')
1301                   {
1302                     errmsg = "illegal character in color spec";
1303                     break;
1304                   } /*if*/
1305                 ++src; /* skip parenthesis/comma */
1306                 skipseparators(&src, srcend);
1307                 if (*src == ')')
1308                   {
1309                     errmsg = "too few color components";
1310                     break;
1311                   } /*if*/
1312                 if
1313                   (
1314                     !parse_color_component
1315                       (
1316                         /*src =*/ &src,
1317                         /*srcend =*/ srcend,
1318                         /*maxvalue =*/ gothue && componentindex == 0 ? 360 : 255,
1319                         /*value =*/ component + componentindex
1320                       )
1321                   )
1322                   {
1323                     errmsg = "illegal number for color component";
1324                     break;
1325                   } /*if*/
1326                 ++componentindex;
1327                 if (componentindex == nrcomponents)
1328                     break;
1329               } /*for*/
1330             if (errmsg != 0)
1331                 break;
1332             skipseparators(&src, srcend);
1333             if (*src++ != ')')
1334               {
1335                 errmsg = "missing close parenthesis";
1336                 break;
1337               } /*if*/
1338             if (src != srcend)
1339               {
1340                 errmsg = "junk after close parenthesis";
1341                 break;
1342               } /*if*/
1343             if (gothue)
1344               {
1345                 component[0] %= 360;
1346               /* convert to RGB using formulas from Wikipedia */
1347                   {
1348                     const int hue = component[0];
1349                     const int chroma =
1350                             (gotlightness ?
1351                                     2
1352                                 *
1353                                     (component[2] < 128 ? component[2] : 255 - component[2])
1354                             :
1355                                 component[2]
1356                             )
1357                         *
1358                             component[1]
1359                         /
1360                             255;
1361                     const int second = chroma * (60 - abs(hue % 120 - 60)) / 60;
1362                     const int brighten =
1363                         gotlightness ?
1364                             component[2] - chroma / 2
1365                         :
1366                             component[2] - chroma;
1367                     int * primary, * secondary, * opposite;
1368                     if (hue < 60)
1369                       {
1370                         primary = component + 0;
1371                         secondary = component + 1;
1372                         opposite = component + 2;
1373                       }
1374                     else if (hue >= 60 && hue < 120)
1375                       {
1376                         primary = component + 1;
1377                         secondary = component + 0;
1378                         opposite = component + 2;
1379                       }
1380                     else if (hue >= 120 && hue < 180)
1381                       {
1382                         primary = component + 1;
1383                         secondary = component + 2;
1384                         opposite = component + 0;
1385                       }
1386                     else if (hue >= 180 && hue < 240)
1387                       {
1388                         primary = component + 2;
1389                         secondary = component + 1;
1390                         opposite = component + 0;
1391                       }
1392                     else if (hue >= 240 && hue < 300)
1393                       {
1394                         primary = component + 2;
1395                         secondary = component + 0;
1396                         opposite = component + 1;
1397                       }
1398                     else /* hue >= 300 && hue < 360 */
1399                       {
1400                         primary = component + 0;
1401                         secondary = component + 2;
1402                         opposite = component + 1;
1403                       } /*if*/
1404                     *primary = chroma + brighten;
1405                     *secondary = second + brighten;
1406                     *opposite = brighten;
1407                   }
1408               }
1409             else if (!gotcolors)
1410               {
1411                 if (gotalpha)
1412                   {
1413                     component[3] = component[1];
1414                   } /*if*/
1415                 component[2] = component[1] = component[0];
1416               } /*if*/
1417             if (!gotalpha)
1418               {
1419                 component[3] = 255;
1420               } /*if*/
1421             result.r = component[0];
1422             result.g = component[1];
1423             result.b = component[2];
1424             result.a = component[3];
1425             break;
1426           } /*if*/
1427         if (nonhex)
1428           {
1429             bool found;
1430             for (colorindex = 0;;)
1431               {
1432                 const named_color * const entry = predefined_color_names + colorindex;
1433                 if (entry->name == 0)
1434                   {
1435                     found = false;
1436                     break;
1437                   } /*if*/
1438                 if (strcasecmp(entry->name, colorstr) == 0)
1439                   {
1440                     result = entry->color;
1441                     found = true;
1442                     break;
1443                   } /*if*/
1444                 ++colorindex;
1445               } /*for*/
1446             if (found)
1447                 break;
1448             if (nonhex)
1449               {
1450                 errmsg = "unrecognized color name";
1451                 break;
1452               } /*if*/
1453           /* allow plain hex string with no preceding "#" for backward compatibility */
1454           } /*if*/
1455       /* must be hex */
1456           {
1457             int componentlength, componentscale, componentindex;
1458             src = colorstr + (colorstr[0] == '#' ? 1 : 0);
1459             if (srcend - src > 12 || (srcend - src) % 3 != 0)
1460               {
1461                 errmsg = "bad hex color string";
1462                 break;
1463               } /*if*/
1464             componentlength = (srcend - src) / 3;
1465             componentscale = (1 << 4 * componentlength) - 1;
1466             for (componentindex = 0; componentindex < 3; ++componentindex)
1467               {
1468                 int component, j;
1469                 unsigned char * dest;
1470                 component = 0;
1471                 for (j = 0; j < componentlength; ++j)
1472                   {
1473                     const unsigned char ch = *src++;
1474                     component =
1475                             component * 16
1476                         +
1477                             (ch >= 'a' && ch <= 'f' ?
1478                                 ch - 'a' + 10
1479                             : ch >= 'A' && ch <= 'F' ?
1480                                 ch - 'A' + 10
1481                             : /* ch >= '0' && ch <= '9' ? */
1482                                 ch - '0'
1483                             );
1484                   } /*for*/
1485                 switch (componentindex)
1486                   {
1487                 case 0:
1488                     dest = &result.r;
1489                 break;
1490                 case 1:
1491                     dest = &result.g;
1492                 break;
1493                 case 2:
1494                     dest = &result.b;
1495                 break;
1496                   } /*switch*/
1497                 *dest = component * 255 / componentscale;
1498               } /*for*/
1499             result.a = 255;
1500           }
1501       }
1502     while (false);
1503     if (errmsg != 0)
1504       {
1505         fprintf(stderr, "ERR:  couldn't parse %s colorspec \"%s\" -- %s\n", what, colorstr, errmsg);
1506         exit(1);
1507       } /*if*/
1508     return result;
1509   } /*parse_color*/
1510