Python: Give goto_url_hook only one argument, like follow_url_hook.
[elinks.git] / src / util / color.c
blob92abadb1e4b7b59660a31bbc9491a9ae818cbdcc
1 /* Color parser */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <ctype.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "elinks.h"
15 #include "util/color.h"
16 #include "util/conv.h"
17 #include "util/fastfind.h"
18 #include "util/string.h"
20 struct color_spec {
21 char *name;
22 color_T rgb;
25 static struct color_spec color_specs[] = {
26 #include "util/color_s.inc"
27 #ifndef CONFIG_SMALL
28 #include "util/color.inc"
29 #endif
30 { NULL, 0}
33 #ifdef USE_FASTFIND
35 static struct color_spec *internal_pointer;
37 static void
38 colors_list_reset(void)
40 internal_pointer = color_specs;
43 /* Returns a pointer to a struct that contains
44 * current key and data pointers and increment
45 * internal pointer.
46 * It returns NULL when key is NULL. */
47 static struct fastfind_key_value *
48 colors_list_next(void)
50 static struct fastfind_key_value kv;
52 if (!internal_pointer->name) return NULL;
54 kv.key = (unsigned char *) internal_pointer->name;
55 kv.data = internal_pointer;
57 internal_pointer++;
59 return &kv;
62 static struct fastfind_index ff_colors_index
63 = INIT_FASTFIND_INDEX("colors_lookup", colors_list_reset, colors_list_next);
65 #endif /* USE_FASTFIND */
67 void
68 init_colors_lookup(void)
70 #ifdef USE_FASTFIND
71 fastfind_index(&ff_colors_index, FF_COMPRESS);
72 #endif
75 void
76 free_colors_lookup(void)
78 #ifdef USE_FASTFIND
79 fastfind_done(&ff_colors_index);
80 #endif
83 int
84 decode_color(unsigned char *str, int slen, color_T *color)
86 if (*str == '#' && (slen == 7 || slen == 4)) {
87 unsigned char buffer[7];
88 unsigned char *end;
89 color_T string_color;
91 str++;
93 decode_hex_color:
94 if (slen == 4) {
95 /* Expand the short hex color format */
96 buffer[0] = buffer[1] = str[0];
97 buffer[2] = buffer[3] = str[1];
98 buffer[4] = buffer[5] = str[2];
99 buffer[6] = 0;
100 str = buffer;
103 errno = 0;
104 string_color = strtoul(str, (char **) &end, 16);
105 if (!errno && (end == str + 6) && string_color <= 0xFFFFFF) {
106 *color = string_color;
107 return 0;
109 } else {
110 struct color_spec *cs;
112 #ifndef USE_FASTFIND
113 for (cs = color_specs; cs->name; cs++)
114 if (!strlcasecmp(cs->name, -1, str, slen))
115 break;
116 #else
117 cs = fastfind_search(&ff_colors_index, str, slen);
118 #endif
119 if (cs && cs->name) {
120 *color = cs->rgb;
121 return 0;
123 } else if (slen == 6 || slen == 3) {
124 /* Check if the string is just the hexadecimal rgb
125 * color notation with the leading '#' missing and
126 * treat it as such. */
127 int len = 0;
129 while (len < slen && isxdigit(str[len])) len++;
131 if (len == slen) goto decode_hex_color;
135 return -1; /* Not found */
138 unsigned char *
139 get_color_string(color_T color, unsigned char hexcolor[8])
141 struct color_spec *cs;
143 for (cs = color_specs; cs->name; cs++)
144 if (cs->rgb == color)
145 return cs->name;
147 color_to_string(color, hexcolor);
148 return hexcolor;
151 void
152 color_to_string(color_T color, unsigned char str[8])
154 str[0]='#';
155 elinks_ulongcat(&str[1], NULL, (unsigned long) color, 6, '0', 16, 0);