2 * Copyright (c) 1984 through 2008, William LeFebvre
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
16 * * Neither the name of William LeFebvre nor the names of other
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Top users/processes display for Unix
39 * This file handles color definitions and access for augmenting
40 * the output with ansi color sequences.
42 * The definition of a color setting is as follows, separated by
45 * tag=minimum,maximum#code
47 * "tag" is the name of the value to display with color.
49 * "minimum" and "maximum" are positive integer values defining a range:
50 * when the value is within this range it will be shown with the
51 * specified color. A missing value indicates that no check should be
52 * made (i.e.: ",25" is n <= 25; "25,50" is 25 <= n <= 50; and "50,"
55 * "code" is the ansi sequence that defines the color to use with the
56 * escape sequence "[m". Semi-colons are allowed in this string to
66 typedef struct color_entry
{
71 struct color_entry
*next
;
72 struct color_entry
*tagnext
;
75 static color_entry
*entries
= NULL
;
77 static color_entry
**bytag
= NULL
;
78 static char **bytag_names
= NULL
;
79 static int totaltags
= 0;
80 static int tagcnt
= 0;
81 static int color_off
= 0;
83 static char **color_ansi
= NULL
;
84 static int num_color_ansi
= 0;
85 static int max_color_ansi
= 0;
93 for (i
= 0; i
< num_color_ansi
; i
++)
95 if (strcmp(color_ansi
[i
], str
) == 0)
101 /* need a new slot */
102 if (num_color_ansi
>= max_color_ansi
)
104 max_color_ansi
+= COLOR_ANSI_SLOTS
;
105 color_ansi
= (char **)realloc(color_ansi
, max_color_ansi
* sizeof(char *));
107 color_ansi
[num_color_ansi
] = strdup(str
);
108 return num_color_ansi
++;
112 * int color_env_parse(char *env)
114 * Parse a color specification "env" (such as one found in the environment) and
115 * add them to the list of entries. Always returns 0. Should only be called
120 color_env_parse(char *env
)
131 color_ansi
= (char **)malloc(COLOR_ANSI_SLOTS
* sizeof(char *));
132 max_color_ansi
= COLOR_ANSI_SLOTS
;
134 /* color slot 0 is always "0" */
139 p
= strtok(env
, ":");
142 if ((min
= strchr(p
, '=')) != NULL
&&
143 (max
= strchr(min
, ',')) != NULL
&&
144 (str
= strchr(max
, '#')) != NULL
)
146 ce
= (color_entry
*)malloc(sizeof(color_entry
));
148 ce
->tag
= (char *)malloc(len
+ 1);
149 strncpy(ce
->tag
, p
, len
);
151 ce
->min
= atoi(++min
);
152 ce
->max
= atoi(++max
);
153 ce
->color
= color_slot(++str
);
167 message_error(" %.*s: bad color entry", len
, p
);
169 p
= strtok(NULL
, ":");
176 * int color_tag(char *tag)
178 * Declare "tag" as a color tag. Return a tag index to use when testing
179 * a value against the tests for this tag. Should not be called before
190 /* check for absurd arguments */
191 if (tag
== NULL
|| *tag
== '\0')
196 dprintf("color_tag(%s)\n", tag
);
198 /* initial allocation */
202 bytag
= (color_entry
**)malloc(totaltags
* sizeof(color_entry
*));
203 bytag_names
= (char **)malloc(totaltags
* sizeof(char *));
206 /* if we dont have enough room then reallocate */
207 if (tagcnt
>= totaltags
)
210 bytag
= (color_entry
**)realloc(bytag
, totaltags
* sizeof(color_entry
*));
211 bytag_names
= (char **)realloc(bytag_names
, totaltags
* sizeof(char *));
214 /* initialize scan */
218 /* look for tag in the list of entries */
219 while (entryp
!= NULL
)
221 if (strcmp(entryp
->tag
, tag
) == 0)
223 entryp
->tagnext
= tp
;
226 entryp
= entryp
->next
;
229 /* we track names in the array bytag */
231 bytag_names
[tagcnt
] = strdup(tag
);
233 /* return this index number as a reference */
234 dprintf("color_tag: returns %d\n", tagcnt
);
239 * int color_test(int tagidx, int value)
241 * Test "value" against tests for tag "tagidx", a number previously returned
242 * by color_tag. Return the correct color number to use when highlighting.
243 * If there is no match, return 0 (color 0).
247 color_test(int tagidx
, int value
)
253 if (tagidx
< 0 || tagidx
>= tagcnt
|| color_off
)
262 if ((!ce
->min
|| ce
->min
<= value
) &&
263 (!ce
->max
|| ce
->max
>= value
))
274 * char *color_setstr(int color)
276 * Return ANSI string to set the terminal for color number "color".
280 color_setstr(int color
)
286 if (color
>= 0 && color
< num_color_ansi
)
288 snprintf(v
, sizeof(v
), "\033[%sm", color_ansi
[color
]);
302 fputs("These color tags are available:", f
);
304 for (i
= 0; i
< tagcnt
; i
++)
306 len
= strlen(bytag_names
[i
]) + 1;
312 fprintf(f
, " %s", bytag_names
[i
]);
316 fputs("\n\nTop color settings:\n", f
);
318 for (i
= 0; i
< tagcnt
; i
++)
323 fprintf(f
, " %s (%d-", ep
->tag
, ep
->min
);
326 fprintf(f
, "%d", ep
->max
);
328 fprintf(f
, "): ansi color %s, %sSample Text",
329 color_ansi
[(int)ep
->color
],
330 color_setstr(ep
->color
));
331 fprintf(f
, "%s\n", color_setstr(0));
344 fprintf(f
, "color debug dump\n");
348 fprintf(f
, "%s(%d,%d): slot %d, ansi %s, %sSample Text",
349 ep
->tag
, ep
->min
, ep
->max
, ep
->color
, color_ansi
[(int)ep
->color
],
350 color_setstr(ep
->color
));
351 fprintf(f
, "%s\n", color_setstr(0));
355 fprintf(f
, "\ntags:");
356 for (i
= 0; i
< tagcnt
; i
++)
358 fprintf(f
, " %s", bytag_names
[i
]);
364 color_activate(int i
)
369 color_off
= !color_off
;