color.c 6.25 KB
Newer Older
1
2
3
4
/* $Id$ */
/**************************************************************************
 *   color.c                                                              *
 *                                                                        *
5
6
 *   Copyright (C) 2001, 2002, 2003, 2004 Chris Allegretta                *
 *   Copyright (C) 2005, 2006 David Lawrence Ramsey                       *
7
8
 *   This program is free software; you can redistribute it and/or modify *
 *   it under the terms of the GNU General Public License as published by *
9
 *   the Free Software Foundation; either version 2, or (at your option)  *
10
11
 *   any later version.                                                   *
 *                                                                        *
12
13
14
15
 *   This program is distributed in the hope that it will be useful, but  *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
 *   General Public License for more details.                             *
16
17
18
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
 *   along with this program; if not, write to the Free Software          *
19
20
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA            *
 *   02110-1301, USA.                                                     *
21
22
23
 *                                                                        *
 **************************************************************************/

24
#include "proto.h"
25
26

#include <stdio.h>
27
#include <string.h>
28

Chris Allegretta's avatar
Chris Allegretta committed
29
30
#ifdef ENABLE_COLOR

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
31
32
/* For each syntax list entry, go through the list of colors and assign
 * color pairs. */
33
void set_colorpairs(void)
34
{
35
36
    const syntaxtype *this_syntax = syntaxes;

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
37
    for (; this_syntax != NULL; this_syntax = this_syntax->next) {
38
39
40
	colortype *this_color = this_syntax->color;
	int color_pair = 1;

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
41
	for (; this_color != NULL; this_color = this_color->next) {
42
43
	    const colortype *beforenow = this_syntax->color;

44
45
46
47
48
	    for (; beforenow != this_color &&
		(beforenow->fg != this_color->fg ||
		beforenow->bg != this_color->bg ||
		beforenow->bright != this_color->bright);
		beforenow = beforenow->next)
49
50
		;

51
	    if (beforenow != this_color)
52
53
54
55
56
57
58
59
		this_color->pairnum = beforenow->pairnum;
	    else {
		this_color->pairnum = color_pair;
		color_pair++;
	    }
	}
    }
}
60

61
/* Initialize the color information. */
62
void color_init(void)
63
{
64
65
    assert(openfile != NULL);

66
    if (has_colors()) {
67
	const colortype *tmpcolor;
68
#ifdef HAVE_USE_DEFAULT_COLORS
69
	bool defok;
70
71
#endif

72
	start_color();
73

74
#ifdef HAVE_USE_DEFAULT_COLORS
75
	/* Use the default colors, if available. */
76
	defok = (use_default_colors() != ERR);
77
#endif
78

79
	for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
80
		tmpcolor = tmpcolor->next) {
81
82
83
84
85
86
87
	    short foreground = tmpcolor->fg, background = tmpcolor->bg;
	    if (foreground == -1) {
#ifdef HAVE_USE_DEFAULT_COLORS
		if (!defok)
#endif
		    foreground = COLOR_WHITE;
	    }
88

89
	    if (background == -1) {
90
#ifdef HAVE_USE_DEFAULT_COLORS
Chris Allegretta's avatar
Chris Allegretta committed
91
		if (!defok)
92
93
#endif
		    background = COLOR_BLACK;
94
	    }
95

96
	    init_pair(tmpcolor->pairnum, foreground, background);
97

98
#ifdef DEBUG
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
99
	    fprintf(stderr, "init_pair(): fg = %hd, bg = %hd\n", tmpcolor->fg, tmpcolor->bg);
100
#endif
101
102
	}
    }
103
104
}

Chris Allegretta's avatar
Chris Allegretta committed
105
/* Update the color information based on the current filename. */
106
void color_update(void)
107
{
108
    const syntaxtype *tmpsyntax;
109
    colortype *tmpcolor, *defcolor = NULL;
110
111

    assert(openfile != NULL);
112

113
    openfile->colorstrings = NULL;
114

115
116
    /* If we specified a syntax override string, use it. */
    if (syntaxstr != NULL) {
117
118
119
120
121
	/* If the syntax override is "none", it's the same as not having
	 * a syntax at all, so get out. */
	if (strcmp(syntaxstr, "none") == 0)
	    return;

122
123
	for (tmpsyntax = syntaxes; tmpsyntax != NULL;
		tmpsyntax = tmpsyntax->next) {
124
	    if (strcmp(tmpsyntax->desc, syntaxstr) == 0)
125
		openfile->colorstrings = tmpsyntax->color;
126

127
	    if (openfile->colorstrings != NULL)
128
		break;
129
130
	}
    }
131

132
133
134
135
    /* If we didn't specify a syntax override string, or if we did and
     * there was no syntax by that name, get the syntax based on the
     * file extension. */
    if (openfile->colorstrings == NULL) {
136
	for (tmpsyntax = syntaxes; tmpsyntax != NULL;
137
		tmpsyntax = tmpsyntax->next) {
138
139
	    exttype *e;

140
	    /* If this is the default syntax, it has no associated
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
141
142
	     * extensions, which we've checked for elsewhere.  Skip over
	     * it here, but keep track of its color regexes. */
143
	    if (strcmp(tmpsyntax->desc, "default") == 0) {
144
		defcolor = tmpsyntax->color;
145
146
147
		continue;
	    }

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
	    for (e = tmpsyntax->extensions; e != NULL; e = e->next) {
		bool not_compiled = (e->ext == NULL);

		/* e->ext_regex has already been checked for validity
		 * elsewhere.  Compile its specified regex if we haven't
		 * already. */
		if (not_compiled) {
		    e->ext = (regex_t *)nmalloc(sizeof(regex_t));
		    regcomp(e->ext, e->ext_regex, REG_EXTENDED);
		}

		/* Set colorstrings if we matched the extension
		 * regex. */
		if (regexec(e->ext, openfile->filename, 0, NULL,
			0) == 0)
		    openfile->colorstrings = tmpsyntax->color;

		if (openfile->colorstrings != NULL)
		    break;

		/* Decompile e->ext_regex's specified regex if we aren't
		 * going to use it. */
		if (not_compiled) {
		    regfree(e->ext);
		    free(e->ext);
		    e->ext = NULL;
		}
	    }
176
177
178
	}
    }

179
180
181
182
183
    /* If we didn't get a syntax based on the file extension, and we
     * have a default syntax, use it. */
    if (openfile->colorstrings == NULL && defcolor != NULL)
	openfile->colorstrings = defcolor;

184
185
    for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
	tmpcolor = tmpcolor->next) {
186
187
188
189
	/* tmpcolor->start_regex and tmpcolor->end_regex have already
	 * been checked for validity elsewhere.  Compile their specified
	 * regexes if we haven't already. */
	if (tmpcolor->start == NULL) {
190
	    tmpcolor->start = (regex_t *)nmalloc(sizeof(regex_t));
191
192
	    regcomp(tmpcolor->start, tmpcolor->start_regex,
		REG_EXTENDED | (tmpcolor->icase ? REG_ICASE : 0));
193
	}
194

195
	if (tmpcolor->end_regex != NULL && tmpcolor->end == NULL) {
196
	    tmpcolor->end = (regex_t *)nmalloc(sizeof(regex_t));
197
198
	    regcomp(tmpcolor->end, tmpcolor->end_regex,
		REG_EXTENDED | (tmpcolor->icase ? REG_ICASE : 0));
199
200
	}
    }
201
202
}

203
#endif /* ENABLE_COLOR */