diff options
Diffstat (limited to 'uxd.c')
-rw-r--r-- | uxd.c | 123 |
1 files changed, 89 insertions, 34 deletions
@@ -65,9 +65,13 @@ extern int optind; #define BAD_FG BLACK #define BAD_BG bad_color +#define HL_NORMAL 0 +#define HL_NORM_INV 1 +#define HL_SPECIAL 2 +#define HL_BAD 3 + int normal_colors[] = { GREEN, YELLOW }; -int cur_normal_color = 0; -int dump_color; +int cur_normal_hilite = 1; int bad_color = RED; int special_color = SPECIAL; @@ -305,13 +309,33 @@ void print_line(void) { dump_column = 0; } -void next_normal_color() { - cur_normal_color++; - cur_normal_color %= (sizeof(normal_colors) / sizeof(int)); +void next_normal_hilite() { + cur_normal_hilite = !cur_normal_hilite; } -void append_color(char *buf, int fgcolor, int bgcolor) { +void append_color(char *buf, int hl_type) { char tmpbuf[100]; + int fgcolor, bgcolor; + + switch(hl_type) { + case HL_NORMAL: + fgcolor = normal_colors[cur_normal_hilite]; + bgcolor = 0; + break; + case HL_NORM_INV: + fgcolor = 0; + bgcolor = normal_colors[cur_normal_hilite]; + break; + case HL_SPECIAL: + fgcolor = special_color; + bgcolor = 0; + break; + default: + case HL_BAD: + fgcolor = BAD_FG; + bgcolor = bad_color; + break; + } sprintf(tmpbuf, "\x1b[%d;3%d", bold, fgcolor); strcat(buf, tmpbuf); @@ -323,7 +347,36 @@ void append_color(char *buf, int fgcolor, int bgcolor) { strcat(buf, tmpbuf); } -void append_color_off(char *buf) { +void append_mono(char *buf, int hl_type) { + char tmpbuf[100]; + int code; + + switch(hl_type) { + case HL_NORMAL: + case HL_NORM_INV: + code = cur_normal_hilite ? 4 : 0; /* underline : normal */ + break; + case HL_SPECIAL: + code = 1; /* bold */ + break; + default: + case HL_BAD: + code = 7; /* reverse video */ + break; + } + + sprintf(tmpbuf, "\x1b[%dm", code); + strcat(buf, tmpbuf); +} + +void append_hilite(char *buf, int hl_type) { + if(mono) + append_mono(buf, hl_type); + else + append_color(buf, hl_type); +} + +void append_hilite_off(char *buf) { strcat(buf, "\x1b[0m"); } @@ -331,13 +384,13 @@ void append_right(char *str) { strcat(right_buf, str); } -void append_left(unsigned char byte, int dash, int fgcolor, int bgcolor) { +void append_left(unsigned char byte, int dash, int hl_type) { char tmpbuf[100]; if(!dump_column) sprintf(left_buf, hex_word_fmt, filepos + display_offset); - append_color(left_buf, fgcolor, bgcolor); + append_hilite(left_buf, hl_type); sprintf(tmpbuf, hex_byte_fmt, byte); strcat(left_buf, tmpbuf); @@ -347,9 +400,9 @@ void append_left(unsigned char byte, int dash, int fgcolor, int bgcolor) { strcat(left_buf, "-"); if(dump_column == (MAX_DUMP_COLS / 2)) strcat(left_buf, "-"); - append_color_off(left_buf); + append_hilite_off(left_buf); } else { - append_color_off(left_buf); + append_hilite_off(left_buf); strcat(left_buf, " "); if(dump_column == (MAX_DUMP_COLS / 2)) strcat(left_buf, " "); @@ -397,8 +450,8 @@ int dump_utf8_char(void) { unsigned char bytes[] = { 0, 0, 0, 0, 0 }; unsigned char *cont_bytes = bytes + 1; char *printable; - int bad = 0, special = 0; - int c, cont_count, i, fg, bg; + int bad = 0, special = 0, hl_type; + int c, cont_count, i; static int byte0; c = fgetc(input); @@ -415,28 +468,33 @@ int dump_utf8_char(void) { check_utf16(byte0, c); } + /* look at 1st byte to find out how long the sequence is */ if(c < 0x7f) { ascii_count++; cont_count = 0; if(c <= ' ' || c == 0x7f) special = 1; - } else if((c & 0xe0) == 0xc0) /* 110xxxxx */ + } else if((c & 0xe0) == 0xc0) { /* 110xxxxx */ cont_count = 1; - else if((c & 0xf0) == 0xe0) /* 1110xxxx */ + } else if((c & 0xf0) == 0xe0) { /* 1110xxxx */ cont_count = 2; - else if((c & 0xf8) == 0xf0) /* 11110xxx */ + } else if((c & 0xf8) == 0xf0) { /* 11110xxx */ cont_count = 3; - else { + } else { + /* high bit set, but not a valid sequence-starter */ cont_count = 0; bad = 1; } + /* read and validate the continuation bytes, if any */ for(i = 0; i < cont_count; i++) { int cb; c = fgetc(input); if(c == EOF) { - /* EOF in mid-sequence */ + /* EOF in mid-sequence. Don't return 0 here, since we still + have to dump the partial sequence. The next call will + give us EOF again. */ cont_count = i; bad = 1; break; @@ -465,36 +523,33 @@ int dump_utf8_char(void) { multi_count++; } + /* decide how to highlight the current character */ if(bad) { - fg = BAD_FG; - bg = BAD_BG; + hl_type = HL_BAD; /* replacement character � is U+FFFD */ printable = "�"; } else if(special) { - fg = special_color; - bg = 0; + hl_type = HL_SPECIAL; printable = get_special(bytes[0]); } else if(cont_count == 2 && is_bom(bytes)) { - fg = special_color; - bg = 0; + hl_type = HL_SPECIAL; printable = "B"; } else { - fg = normal_colors[cur_normal_color]; - bg = 0; + hl_type = HL_NORMAL; printable = (char *)bytes; - next_normal_color(); + next_normal_hilite(); } - append_color(right_buf, fg, bg); + /* human-readable (right) column: */ + append_hilite(right_buf, hl_type); append_right(printable); - append_color_off(right_buf); - - if(hilite_multi && cont_count) { - c = bg; bg = fg; fg = c; - } + append_hilite_off(right_buf); + /* hex columns: */ + if(hilite_multi && cont_count) + hl_type = HL_NORM_INV; for(i = 0; i <= cont_count; i++) { - append_left(bytes[i], (i != cont_count), fg, bg); + append_left(bytes[i], (i != cont_count), hl_type); } return 1; |