[textview] cleanup the ansi scrubber

pull/69/head
Timothy Stack 11 years ago
parent 5d478fc17a
commit 8754b45699

@ -191,6 +191,22 @@ public:
iter->length());
};
void reset(const char *str, size_t off = 0, size_t len = -1) {
this->pi_string = str;
this->pi_offset = off;
this->pi_next_offset = off;
if (this->pi_length == (size_t)-1) {
this->pi_length = strlen(str);
}
else {
this->pi_length = len;
}
}
void reset(const std::string &str, size_t off = 0) {
this->reset(str.c_str(), off, str.length());
}
size_t pi_offset;
size_t pi_next_offset;
size_t pi_length;

@ -32,6 +32,7 @@
#include <vector>
#include <algorithm>
#include "pcrepp.hh"
#include "lnav_util.hh"
#include "data_parser.hh"
#include "textview_curses.hh"
@ -55,111 +56,92 @@ public:
void scrub_value(string &str, string_attrs_t &sa)
{
vector<line_range> range_queue;
view_colors &vc = view_colors::singleton();
vector<pair<string, string_attr_t> > attr_queue;
int rc, matches[60];
do {
rc = pcre_exec(this->as_pcre,
NULL,
str.c_str(),
str.size(),
0,
0,
matches,
60);
if (rc > 0) {
int c_start = matches[0];
int c_end = matches[1];
struct line_range lr;
bool has_attrs = false;
int attrs = 0;
int lpc;
switch (str[matches[4]]) {
case 'm':
for (lpc = matches[2];
lpc != (int)string::npos && lpc < matches[3]; ) {
int ansi_code = 0;
if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) {
switch (ansi_code) {
case 1:
attrs |= A_BOLD;
break;
case 2:
attrs |= A_DIM;
break;
case 4:
attrs |= A_UNDERLINE;
break;
case 7:
attrs |= A_REVERSE;
break;
case 31:
attrs |= COLOR_PAIR(view_colors::VC_RED);
break;
case 32:
attrs |= COLOR_PAIR(view_colors::VC_GREEN);
break;
case 33:
attrs |= COLOR_PAIR(view_colors::VC_YELLOW);
break;
case 34:
attrs |= COLOR_PAIR(view_colors::VC_BLUE);
break;
case 35:
attrs |= COLOR_PAIR(view_colors::VC_MAGENTA);
break;
case 36:
attrs |= COLOR_PAIR(view_colors::VC_CYAN);
break;
case 37:
attrs |= COLOR_PAIR(view_colors::VC_WHITE);
break;
}
pcre_context_static<60> context;
vector<line_range> range_queue;
pcre_input pi(str);
while (this->as_regex.match(context, pi)) {
pcre_context::capture_t *caps = context.all();
struct line_range lr;
bool has_attrs = false;
int attrs = 0;
int bg = 0;
int fg = 0;
int lpc;
switch (pi.get_substr_start(&caps[2])[0]) {
case 'm':
for (lpc = caps[1].c_begin;
lpc != (int)string::npos && lpc < caps[1].c_end; ) {
int ansi_code = 0;
if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) {
if (90 <= ansi_code && ansi_code <= 97) {
ansi_code -= 60;
attrs |= A_STANDOUT;
}
lpc = str.find(";", lpc);
if (lpc != (int)string::npos) {
lpc += 1;
if (30 <= ansi_code && ansi_code <= 37) {
fg = ansi_code - 30;
}
if (40 <= ansi_code && ansi_code <= 47) {
bg = ansi_code - 40;
}
switch (ansi_code) {
case 1:
attrs |= A_BOLD;
break;
case 2:
attrs |= A_DIM;
break;
case 4:
attrs |= A_UNDERLINE;
break;
case 7:
attrs |= A_REVERSE;
break;
}
}
lpc = str.find(";", lpc);
if (lpc != (int)string::npos) {
lpc += 1;
}
has_attrs = true;
break;
}
if (fg != 0 || bg != 0) {
attrs |= vc.ansi_color_pair(fg, bg);
}
has_attrs = true;
break;
case 'C':
case 'C':
{
int spaces = 0;
if (sscanf(&(str[matches[2]]), "%d", &spaces) == 1) {
str.insert(c_end, spaces, ' ');
if (sscanf(&(str[caps[1].c_begin]), "%d", &spaces) == 1) {
str.insert(caps[0].c_end, spaces, ' ');
}
}
break;
}
str.erase(str.begin() + c_start, str.begin() + c_end);
}
str.erase(str.begin() + caps[0].c_begin,
str.begin() + caps[0].c_end);
if (has_attrs) {
if (!range_queue.empty()) {
range_queue.back().lr_end = c_start;
}
lr.lr_start = c_start;
lr.lr_end = -1;
range_queue.push_back(lr);
attr_queue.push_back(make_string_attr("style", attrs));
if (has_attrs) {
if (!range_queue.empty()) {
range_queue.back().lr_end = caps[0].c_begin;
}
lr.lr_start = caps[0].c_begin;
lr.lr_end = -1;
range_queue.push_back(lr);
attr_queue.push_back(make_string_attr("style", attrs));
}
} while (rc > 0);
pi.reset(str);
}
for (size_t lpc = 0; lpc < range_queue.size(); lpc++) {
sa[range_queue[lpc]].insert(attr_queue[lpc]);
@ -167,26 +149,11 @@ public:
};
private:
pcre *build_pcre(const char *pattern) /* XXX refactor me */
{
const char *errptr;
pcre * retval;
int eoff;
retval = pcre_compile(pattern, 0, &errptr, &eoff, NULL);
if (retval == NULL) {
throw errptr;
}
return retval;
};
ansi_scrubber()
{
this->as_pcre = this->build_pcre("\x1b\\[([\\d=;]*)([a-zA-Z])");
: as_regex("\x1b\\[([\\d=;]*)([a-zA-Z])") {
};
pcre *as_pcre;
pcrepp as_regex;
};
textview_curses::textview_curses()

@ -237,6 +237,17 @@ view_colors::view_colors()
void view_colors::init(void)
{
if (has_colors()) {
static int ansi_colors_to_curses[] = {
COLOR_BLACK,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW,
COLOR_BLUE,
COLOR_MAGENTA,
COLOR_CYAN,
COLOR_WHITE,
};
start_color();
/* use_default_colors(); */
@ -262,6 +273,14 @@ void view_colors::init(void)
init_pair(VC_GRAY, COLOR_BLACK, COLOR_BLACK);
for (int fg = 0; fg < 8; fg++) {
for (int bg = 0; bg < 8; bg++) {
init_pair(ansi_color_pair_index(fg, bg),
ansi_colors_to_curses[fg],
ansi_colors_to_curses[bg]);
}
}
for (int lpc = 0; lpc < 8; lpc++) {
short gradient_value = (1000 / 8) * lpc;

@ -414,9 +414,20 @@ public:
VC_GRAY,
VC_ANSI_START,
VC_ANSI_END = VC_ANSI_START + (8 * 8),
VC_GRADIENT_START,
};
static inline int ansi_color_pair_index(int fg, int bg) {
return VC_ANSI_START + ((fg * 8) + bg);
};
int ansi_color_pair(int fg, int bg) {
return COLOR_PAIR(ansi_color_pair_index(fg, bg));
};
private:
/** The number of colors used for highlighting. */

@ -156,6 +156,7 @@ dist_noinst_SCRIPTS = \
test_vt52_curses.sh
dist_noinst_DATA = \
ansi-colors.0.in \
datafile_simple.0 \
datafile_simple.1 \
datafile_simple.2 \

@ -721,6 +721,7 @@ dist_noinst_SCRIPTS = \
test_vt52_curses.sh
dist_noinst_DATA = \
ansi-colors.0.in \
datafile_simple.0 \
datafile_simple.1 \
datafile_simple.2 \

@ -0,0 +1,22 @@
Basic ANSI colors (eight-color, or dim)
black  black  red  green  yellow  blue  magenta cyan  white 
bold black  black  red  green  yellow  blue  magenta cyan  white 
red  black  red  green  yellow  blue  magenta cyan  white 
bold red  black  red  green  yellow  blue  magenta cyan  white 
green  black  red  green  yellow  blue  magenta cyan  white 
bold green  black  red  green  yellow  blue  magenta cyan  white 
yellow  black  red  green  yellow  blue  magenta cyan  white 
bold yellow  black  red  green  yellow  blue  magenta cyan  white 
blue  black  red  green  yellow  blue  magenta cyan  white 
bold blue  black  red  green  yellow  blue  magenta cyan  white 
magenta  black  red  green  yellow  blue  magenta cyan  white 
bold magenta  black  red  green  yellow  blue  magenta cyan  white 
cyan  black  red  green  yellow  blue  magenta cyan  white 
bold cyan  black  red  green  yellow  blue  magenta cyan  white 
white  black  red  green  yellow  blue  magenta cyan  white 
bold white  black  red  green  yellow  blue  magenta cyan  white 
Attributes: bold dark italic underline blink concealed
 testing  testing  testing  testing  testing  testing 
Loading…
Cancel
Save