Move view declarations to new view header
[tig.git] / src / line.c
blobabf8e7144a0fdca53ebeecb48f11a6f22b7db262
1 /* Copyright (c) 2006-2014 Jonas Fonseca <fonseca@diku.dk>
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include "tig.h"
15 #include "types.h"
16 #include "refs.h"
17 #include "line.h"
18 #include "util.h"
20 static struct line_info *line_info;
21 static size_t line_infos;
23 static struct line_info **color_pair;
24 static size_t color_pairs;
26 DEFINE_ALLOCATOR(realloc_line_info, struct line_info, 8)
27 DEFINE_ALLOCATOR(realloc_color_pair, struct line_info *, 8)
29 enum line_type
30 get_line_type(const char *line)
32 int linelen = strlen(line);
33 enum line_type type;
35 for (type = 0; type < line_infos; type++)
36 /* Case insensitive search matches Signed-off-by lines better. */
37 if (line_info[type].linelen && linelen >= line_info[type].linelen &&
38 !strncasecmp(line_info[type].line, line, line_info[type].linelen))
39 return type;
41 return LINE_DEFAULT;
44 enum line_type
45 get_line_type_from_ref(const struct ref *ref)
47 if (ref->head)
48 return LINE_MAIN_HEAD;
49 else if (ref->ltag)
50 return LINE_MAIN_LOCAL_TAG;
51 else if (ref->tag)
52 return LINE_MAIN_TAG;
53 else if (ref->tracked)
54 return LINE_MAIN_TRACKED;
55 else if (ref->remote)
56 return LINE_MAIN_REMOTE;
57 else if (ref->replace)
58 return LINE_MAIN_REPLACE;
60 return LINE_MAIN_REF;
63 struct line_info *
64 get_line_info(enum line_type type)
66 assert(type < line_infos);
67 return &line_info[type];
70 static struct line_info *
71 add_line_info(const char *name, size_t namelen, const char *line, size_t linelen)
73 struct line_info *info = NULL;
75 if (!realloc_line_info(&line_info, line_infos, 1))
76 die("Failed to allocate line info");
78 info = &line_info[line_infos++];
79 info->name = name;
80 info->namelen = namelen;
81 info->line = line;
82 info->linelen = linelen;
84 return info;
87 #define ADD_LINE_INFO(type, line) \
88 add_line_info(#type, STRING_SIZE(#type), (line), STRING_SIZE(line))
90 struct line_info *
91 find_line_info(const char *name, size_t namelen, bool line_only)
93 enum line_type type;
95 if (!line_infos) {
96 LINE_INFO(ADD_LINE_INFO);
99 for (type = 0; type < line_infos; type++) {
100 struct line_info *info = &line_info[type];
102 if (!line_only && enum_equals(*info, name, namelen))
103 return info;
104 if (info->linelen && namelen >= info->linelen &&
105 !strncasecmp(info->line, name, info->linelen))
106 return info;
109 return NULL;
112 struct line_info *
113 add_custom_color(const char *quoted_line)
115 size_t linelen = strlen(quoted_line) - 2;
116 struct line_info *info = find_line_info(quoted_line + 1, linelen, TRUE);
117 char *line;
119 if (info)
120 return info;
122 line = strndup(quoted_line + 1, linelen);
123 if (!line)
124 return NULL;
126 info = add_line_info(line, linelen, line, linelen);
127 if (!info)
128 free(line);
129 return info;
132 static void
133 init_line_info_color_pair(struct line_info *info, enum line_type type,
134 int default_bg, int default_fg)
136 int bg = info->bg == COLOR_DEFAULT ? default_bg : info->bg;
137 int fg = info->fg == COLOR_DEFAULT ? default_fg : info->fg;
138 int i;
140 for (i = 0; i < color_pairs; i++) {
141 if (color_pair[i]->fg == info->fg && color_pair[i]->bg == info->bg) {
142 info->color_pair = i;
143 return;
147 if (!realloc_color_pair(&color_pair, color_pairs, 1))
148 die("Failed to alloc color pair");
150 color_pair[color_pairs] = info;
151 info->color_pair = color_pairs++;
152 init_pair(COLOR_ID(info->color_pair), fg, bg);
155 void
156 init_colors(void)
158 int default_bg = line_info[LINE_DEFAULT].bg;
159 int default_fg = line_info[LINE_DEFAULT].fg;
160 enum line_type type;
162 start_color();
164 if (assume_default_colors(default_fg, default_bg) == ERR) {
165 default_bg = COLOR_BLACK;
166 default_fg = COLOR_WHITE;
169 for (type = 0; type < line_infos; type++) {
170 struct line_info *info = &line_info[type];
172 init_line_info_color_pair(info, type, default_bg, default_fg);
176 /* vim: set ts=8 sw=8 noexpandtab: */