aboutsummaryrefslogtreecommitdiff
path: root/uxd.c
diff options
context:
space:
mode:
Diffstat (limited to 'uxd.c')
-rw-r--r--uxd.c123
1 files changed, 89 insertions, 34 deletions
diff --git a/uxd.c b/uxd.c
index 93368a1..22a25f3 100644
--- a/uxd.c
+++ b/uxd.c
@@ -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;