diff --git a/src/viewer/dump/dump-color-mode.h b/src/viewer/dump/dump-color-mode.h index 60212d81..3bd0e336 100644 --- a/src/viewer/dump/dump-color-mode.h +++ b/src/viewer/dump/dump-color-mode.h @@ -1,262 +1,46 @@ -/* Color modes for dumping to a file. +/* Partially specialized functions for dumping to a file. * - * dump.c includes this file multiple times, once for each color mode. - * Each time, it defines at most one of the following macros: + * This include file defines a function that dumps the document to a + * file. The function is specialized to one color mode. This is + * supposedly faster than runtime checks. The file that includes this + * file must define several macros to select the specialization. + * + * The following macros must be defined as names of functions that + * this file should define: + * + * - DUMP_FUNCTION_COLOR: The main function. It calls one of the others. + * - DUMP_FUNCTION_UNIBYTE: For dumping in unibyte charsets. + * - DUMP_FUNCTION_UTF8: For dumping in the UTF-8 charset. + * (The function names could be generated with the ## preprocessor + * operator, but that would make grepping more difficult.) + * + * At most one of the following macros may be defined: * * - DUMP_COLOR_MODE_16 * - DUMP_COLOR_MODE_256 * - DUMP_COLOR_MODE_TRUE - * - * This file then defines a dumping function specifically for that - * color mode. This is supposedly faster than runtime checks. */ + */ + +#define DUMP_FUNCTION_SPECIALIZED DUMP_FUNCTION_UNIBYTE +#include "dump-specialized.h" +#undef DUMP_FUNCTION_SPECIALIZED + +#ifdef CONFIG_UTF8 +# define DUMP_CHARSET_UTF8 +# define DUMP_FUNCTION_SPECIALIZED DUMP_FUNCTION_UTF8 +# include "dump-specialized.h" +# undef DUMP_FUNCTION_SPECIALIZED +# undef DUMP_CHARSET_UTF8 +#endif /* CONFIG_UTF8 */ -#ifdef DUMP_COLOR_MODE_16 static int -dump_to_file_16(struct document *document, int fd) -#elif defined(DUMP_COLOR_MODE_256) -static int -dump_to_file_256(struct document *document, int fd) -#elif defined(DUMP_COLOR_MODE_TRUE) -static int -dump_to_file_true_color(struct document *document, int fd) -#else -int -dump_to_file(struct document *document, int fd) -#endif +DUMP_FUNCTION_COLOR(struct document *document, int fd, + unsigned char buf[D_BUF]) { - int y; - int bptr = 0; - unsigned char *buf = mem_alloc(D_BUF); -#ifdef DUMP_COLOR_MODE_16 - unsigned char color = 0; - int width = get_opt_int("document.dump.width"); -#elif defined(DUMP_COLOR_MODE_256) - unsigned char foreground = 0; - unsigned char background = 0; - int width = get_opt_int("document.dump.width"); -#elif defined(DUMP_COLOR_MODE_TRUE) - static unsigned char color[6] = {255, 255, 255, 0, 0, 0}; - unsigned char *foreground = &color[0]; - unsigned char *background = &color[3]; - int width = get_opt_int("document.dump.width"); -#endif /* DUMP_COLOR_MODE_TRUE */ - - if (!buf) return -1; - #ifdef CONFIG_UTF8 if (is_cp_utf8(document->options.cp)) - goto utf8; -#endif /* CONFIG_UTF8 */ + return DUMP_FUNCTION_UTF8(document, fd, buf); +#endif /* CONFIG_UTF8 */ - for (y = 0; y < document->height; y++) { - int white = 0; - int x; - -#ifdef DUMP_COLOR_MODE_16 - write_color_16(color, fd, buf, &bptr); -#elif defined(DUMP_COLOR_MODE_256) - write_color_256("38", foreground, fd, buf, &bptr); - write_color_256("48", background, fd, buf, &bptr); -#elif defined(DUMP_COLOR_MODE_TRUE) - write_true_color("38", foreground, fd, buf, &bptr); - write_true_color("48", background, fd, buf, &bptr); -#endif /* DUMP_COLOR_MODE_TRUE */ - - for (x = 0; x < document->data[y].length; x++) { - unsigned char c; - unsigned char attr = document->data[y].chars[x].attr; -#ifdef DUMP_COLOR_MODE_16 - unsigned char color1 = document->data[y].chars[x].color[0]; - - if (color != color1) { - color = color1; - if (write_color_16(color, fd, buf, &bptr)) - goto fail; - } -#elif defined(DUMP_COLOR_MODE_256) - unsigned char color1 = document->data[y].chars[x].color[0]; - unsigned char color2 = document->data[y].chars[x].color[1]; - - if (foreground != color1) { - foreground = color1; - if (write_color_256("38", foreground, fd, buf, &bptr)) - goto fail; - } - - if (background != color2) { - background = color2; - if (write_color_256("48", background, fd, buf, &bptr)) - goto fail; - } -#elif defined(DUMP_COLOR_MODE_TRUE) - unsigned char *new_foreground = &document->data[y].chars[x].color[0]; - unsigned char *new_background = &document->data[y].chars[x].color[3]; - - if (memcmp(foreground, new_foreground, 3)) { - foreground = new_foreground; - if (write_true_color("38", foreground, fd, buf, &bptr)) - goto fail; - } - - if (memcmp(background, new_background, 3)) { - background = new_background; - if (write_true_color("48", background, fd, buf, &bptr)) - goto fail; - } -#endif /* DUMP_COLOR_MODE_TRUE */ - - c = document->data[y].chars[x].data; - - if ((attr & SCREEN_ATTR_FRAME) - && c >= 176 && c < 224) - c = frame_dumb[c - 176]; - - if (c <= ' ') { - /* Count spaces. */ - white++; - continue; - } - - /* Print spaces if any. */ - while (white) { - if (write_char(' ', fd, buf, &bptr)) - goto fail; - white--; - } - - /* Print normal char. */ - if (write_char(c, fd, buf, &bptr)) - goto fail; - } -#if defined(DUMP_COLOR_MODE_16) || defined(DUMP_COLOR_MODE_256) || defined(DUMP_COLOR_MODE_TRUE) - for (;x < width; x++) { - if (write_char(' ', fd, buf, &bptr)) - goto fail; - } -#endif /* DUMP_COLOR_MODE_16 || DUMP_COLOR_MODE_256 || DUMP_COLOR_MODE_TRUE */ - - /* Print end of line. */ - if (write_char('\n', fd, buf, &bptr)) - goto fail; - } -#ifdef CONFIG_UTF8 - goto ref; -utf8: - for (y = 0; y < document->height; y++) { - int white = 0; - int x; - -#ifdef DUMP_COLOR_MODE_16 - write_color_16(color, fd, buf, &bptr); -#elif defined(DUMP_COLOR_MODE_256) - write_color_256("38", foreground, fd, buf, &bptr); - write_color_256("48", background, fd, buf, &bptr); -#elif defined(DUMP_COLOR_MODE_TRUE) - write_true_color("38", foreground, fd, buf, &bptr); - write_true_color("48", background, fd, buf, &bptr); -#endif /* DUMP_COLOR_MODE_TRUE */ - - for (x = 0; x < document->data[y].length; x++) { - unicode_val_T c; - unsigned char attr = document->data[y].chars[x].attr; -#ifdef DUMP_COLOR_MODE_16 - unsigned char color1 = document->data[y].chars[x].color[0]; - - if (color != color1) { - color = color1; - if (write_color_16(color, fd, buf, &bptr)) - goto fail; - } -#elif defined(DUMP_COLOR_MODE_256) - unsigned char color1 = document->data[y].chars[x].color[0]; - unsigned char color2 = document->data[y].chars[x].color[1]; - - if (foreground != color1) { - foreground = color1; - if (write_color_256("38", foreground, fd, buf, &bptr)) - goto fail; - } - - if (background != color2) { - background = color2; - if (write_color_256("48", background, fd, buf, &bptr)) - goto fail; - } -#elif defined(DUMP_COLOR_MODE_TRUE) - unsigned char *new_foreground = &document->data[y].chars[x].color[0]; - unsigned char *new_background = &document->data[y].chars[x].color[3]; - - if (memcmp(foreground, new_foreground, 3)) { - foreground = new_foreground; - if (write_true_color("38", foreground, fd, buf, &bptr)) - goto fail; - } - - if (memcmp(background, new_background, 3)) { - background = new_background; - if (write_true_color("48", background, fd, buf, &bptr)) - goto fail; - } -#endif /* DUMP_COLOR_MODE_TRUE */ - - c = document->data[y].chars[x].data; - - if ((attr & SCREEN_ATTR_FRAME) - && c >= 176 && c < 224) - c = frame_dumb[c - 176]; - else { - unsigned char *utf8_buf = encode_utf8(c); - - while (*utf8_buf) { - if (write_char(*utf8_buf++, - fd, buf, &bptr)) goto fail; - } - - x += unicode_to_cell(c) - 1; - - continue; - } - - if (c <= ' ') { - /* Count spaces. */ - white++; - continue; - } - - /* Print spaces if any. */ - while (white) { - if (write_char(' ', fd, buf, &bptr)) - goto fail; - white--; - } - - /* Print normal char. */ - if (write_char(c, fd, buf, &bptr)) - goto fail; - } -#if defined(DUMP_COLOR_MODE_16) || defined(DUMP_COLOR_MODE_256) || defined(DUMP_COLOR_MODE_TRUE) - for (;x < width; x++) { - if (write_char(' ', fd, buf, &bptr)) - goto fail; - } -#endif /* DUMP_COLOR_MODE_16 || DUMP_COLOR_MODE_256 || DUMP_COLOR_MODE_TRUE */ - - /* Print end of line. */ - if (write_char('\n', fd, buf, &bptr)) - goto fail; - } -ref: -#endif /* CONFIG_UTF8 */ - - if (hard_write(fd, buf, bptr) != bptr) { -fail: - mem_free(buf); - return -1; - } - - if (dump_references(document, fd, buf)) - goto fail; - - mem_free(buf); - return 0; + return DUMP_FUNCTION_UNIBYTE(document, fd, buf); } diff --git a/src/viewer/dump/dump-specialized.h b/src/viewer/dump/dump-specialized.h new file mode 100644 index 00000000..f60aeed3 --- /dev/null +++ b/src/viewer/dump/dump-specialized.h @@ -0,0 +1,159 @@ +/* Fully specialized functions for dumping to a file. + * + * This include file defines a function that dumps the document to a + * file. The function is specialized to one color mode and one kind + * of charset. This is supposedly faster than runtime checks. The + * file that includes this file must define several macros to select + * the specialization. + * + * The following macro must be defined: + * + * - DUMP_FUNCTION_SPECIALIZED: The name of the function that this + * file should define. + * + * At most one of the following macros may be defined: + * + * - DUMP_COLOR_MODE_16 + * - DUMP_COLOR_MODE_256 + * - DUMP_COLOR_MODE_TRUE + * + * The following macro may be defined: + * + * - DUMP_CHARSET_UTF8 + */ + +static int +DUMP_FUNCTION_SPECIALIZED(struct document *document, int fd, + unsigned char buf[D_BUF]) +{ + int y; + int bptr = 0; +#ifdef DUMP_COLOR_MODE_16 + unsigned char color = 0; + int width = get_opt_int("document.dump.width"); +#elif defined(DUMP_COLOR_MODE_256) + unsigned char foreground = 0; + unsigned char background = 0; + int width = get_opt_int("document.dump.width"); +#elif defined(DUMP_COLOR_MODE_TRUE) + static unsigned char color[6] = {255, 255, 255, 0, 0, 0}; + unsigned char *foreground = &color[0]; + unsigned char *background = &color[3]; + int width = get_opt_int("document.dump.width"); +#endif /* DUMP_COLOR_MODE_TRUE */ + + for (y = 0; y < document->height; y++) { + int white = 0; + int x; + +#ifdef DUMP_COLOR_MODE_16 + write_color_16(color, fd, buf, &bptr); +#elif defined(DUMP_COLOR_MODE_256) + write_color_256("38", foreground, fd, buf, &bptr); + write_color_256("48", background, fd, buf, &bptr); +#elif defined(DUMP_COLOR_MODE_TRUE) + write_true_color("38", foreground, fd, buf, &bptr); + write_true_color("48", background, fd, buf, &bptr); +#endif /* DUMP_COLOR_MODE_TRUE */ + + for (x = 0; x < document->data[y].length; x++) { +#ifdef DUMP_CHARSET_UTF8 + unicode_val_T c; +#else + unsigned char c; +#endif + unsigned char attr = document->data[y].chars[x].attr; +#ifdef DUMP_COLOR_MODE_16 + unsigned char color1 = document->data[y].chars[x].color[0]; + + if (color != color1) { + color = color1; + if (write_color_16(color, fd, buf, &bptr)) + return -1; + } +#elif defined(DUMP_COLOR_MODE_256) + unsigned char color1 = document->data[y].chars[x].color[0]; + unsigned char color2 = document->data[y].chars[x].color[1]; + + if (foreground != color1) { + foreground = color1; + if (write_color_256("38", foreground, fd, buf, &bptr)) + return -1; + } + + if (background != color2) { + background = color2; + if (write_color_256("48", background, fd, buf, &bptr)) + return -1; + } +#elif defined(DUMP_COLOR_MODE_TRUE) + unsigned char *new_foreground = &document->data[y].chars[x].color[0]; + unsigned char *new_background = &document->data[y].chars[x].color[3]; + + if (memcmp(foreground, new_foreground, 3)) { + foreground = new_foreground; + if (write_true_color("38", foreground, fd, buf, &bptr)) + return -1; + } + + if (memcmp(background, new_background, 3)) { + background = new_background; + if (write_true_color("48", background, fd, buf, &bptr)) + return -1; + } +#endif /* DUMP_COLOR_MODE_TRUE */ + + c = document->data[y].chars[x].data; + + if ((attr & SCREEN_ATTR_FRAME) + && c >= 176 && c < 224) + c = frame_dumb[c - 176]; +#ifdef DUMP_CHARSET_UTF8 + else { + unsigned char *utf8_buf = encode_utf8(c); + + while (*utf8_buf) { + if (write_char(*utf8_buf++, + fd, buf, &bptr)) return -1; + } + + x += unicode_to_cell(c) - 1; + + continue; + } +#endif /* DUMP_CHARSET_UTF8 */ + + if (c <= ' ') { + /* Count spaces. */ + white++; + continue; + } + + /* Print spaces if any. */ + while (white) { + if (write_char(' ', fd, buf, &bptr)) + return -1; + white--; + } + + /* Print normal char. */ + if (write_char(c, fd, buf, &bptr)) + return -1; + } +#if defined(DUMP_COLOR_MODE_16) || defined(DUMP_COLOR_MODE_256) || defined(DUMP_COLOR_MODE_TRUE) + for (;x < width; x++) { + if (write_char(' ', fd, buf, &bptr)) + return -1; + } +#endif /* DUMP_COLOR_MODE_16 || DUMP_COLOR_MODE_256 || DUMP_COLOR_MODE_TRUE */ + + /* Print end of line. */ + if (write_char('\n', fd, buf, &bptr)) + return -1; + } + + if (hard_write(fd, buf, bptr) != bptr) + return -1; + + return 0; +} diff --git a/src/viewer/dump/dump.c b/src/viewer/dump/dump.c index d4957ff8..db8cbb4e 100644 --- a/src/viewer/dump/dump.c +++ b/src/viewer/dump/dump.c @@ -51,14 +51,251 @@ static int dump_pos; static struct download dump_download; static int dump_redir_count = 0; -static int dump_to_file_16(struct document *document, int fd); +#define D_BUF 65536 + +static int +write_char(unsigned char c, int fd, unsigned char *buf, int *bptr) +{ + buf[(*bptr)++] = c; + if ((*bptr) >= D_BUF) { + if (hard_write(fd, buf, (*bptr)) != (*bptr)) + return -1; + (*bptr) = 0; + } + + return 0; +} + +static int +write_color_16(unsigned char color, int fd, unsigned char *buf, int *bptr) +{ + unsigned char bufor[] = "\033[0;30;40m"; + unsigned char *data = bufor; + int background = (color >> 4) & 7; + int foreground = color & 7; + + bufor[5] += foreground; + if (background) bufor[8] += background; + else { + bufor[6] = 'm'; + bufor[7] = '\0'; + } + while(*data) { + if (write_char(*data++, fd, buf, bptr)) return -1; + } + return 0; +} + +#define DUMP_COLOR_MODE_16 +#define DUMP_FUNCTION_COLOR dump_16color +#define DUMP_FUNCTION_UTF8 dump_16color_utf8 +#define DUMP_FUNCTION_UNIBYTE dump_16color_unibyte +#include "dump-color-mode.h" +#undef DUMP_COLOR_MODE_16 +#undef DUMP_FUNCTION_COLOR +#undef DUMP_FUNCTION_UTF8 +#undef DUMP_FUNCTION_UNIBYTE + +/* configure --enable-debug uses gcc -Wall -Werror, and -Wall includes + * -Wunused-function, so declaring or defining any unused function + * would break the build. */ #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) -static int dump_to_file_256(struct document *document, int fd); -#endif + +static int +write_color_256(unsigned char *str, unsigned char color, int fd, unsigned char *buf, int *bptr) +{ + unsigned char bufor[16]; + unsigned char *data = bufor; + + snprintf(bufor, 16, "\033[%s;5;%dm", str, color); + while(*data) { + if (write_char(*data++, fd, buf, bptr)) return -1; + } + return 0; +} + +#define DUMP_COLOR_MODE_256 +#define DUMP_FUNCTION_COLOR dump_256color +#define DUMP_FUNCTION_UTF8 dump_256color_utf8 +#define DUMP_FUNCTION_UNIBYTE dump_256color_unibyte +#include "dump-color-mode.h" +#undef DUMP_COLOR_MODE_256 +#undef DUMP_FUNCTION_COLOR +#undef DUMP_FUNCTION_UTF8 +#undef DUMP_FUNCTION_UNIBYTE + +#endif /* defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) */ + #ifdef CONFIG_TRUE_COLOR -static int dump_to_file_true_color(struct document *document, int fd); + +static int +write_true_color(unsigned char *str, unsigned char *color, int fd, unsigned char *buf, int *bptr) +{ + unsigned char bufor[24]; + unsigned char *data = bufor; + + snprintf(bufor, 24, "\033[%s;2;%d;%d;%dm", str, color[0], color[1], color[2]); + while(*data) { + if (write_char(*data++, fd, buf, bptr)) return -1; + } + return 0; +} + +#define DUMP_COLOR_MODE_TRUE +#define DUMP_FUNCTION_COLOR dump_truecolor +#define DUMP_FUNCTION_UTF8 dump_truecolor_utf8 +#define DUMP_FUNCTION_UNIBYTE dump_truecolor_unibyte +#include "dump-color-mode.h" +#undef DUMP_COLOR_MODE_TRUE +#undef DUMP_FUNCTION_COLOR +#undef DUMP_FUNCTION_UTF8 +#undef DUMP_FUNCTION_UNIBYTE + +#endif /* CONFIG_TRUE_COLOR */ + +#define DUMP_FUNCTION_COLOR dump_nocolor +#define DUMP_FUNCTION_UTF8 dump_nocolor_utf8 +#define DUMP_FUNCTION_UNIBYTE dump_nocolor_unibyte +#include "dump-color-mode.h" +#undef DUMP_FUNCTION_COLOR +#undef DUMP_FUNCTION_UTF8 +#undef DUMP_FUNCTION_UNIBYTE + +/*! @return 0 on success, -1 on error */ +static int +dump_references(struct document *document, int fd, unsigned char buf[D_BUF]) +{ + if (document->nlinks && get_opt_bool("document.dump.references")) { + int x; + unsigned char *header = "\nReferences\n\n Visible links\n"; + int headlen = strlen(header); + + if (hard_write(fd, header, headlen) != headlen) + return -1; + + for (x = 0; x < document->nlinks; x++) { + struct link *link = &document->links[x]; + unsigned char *where = link->where; + size_t reflen; + + if (!where) continue; + + if (document->options.links_numbering) { + if (link->title && *link->title) + snprintf(buf, D_BUF, "%4d. %s\n\t%s\n", + x + 1, link->title, where); + else + snprintf(buf, D_BUF, "%4d. %s\n", + x + 1, where); + } else { + if (link->title && *link->title) + snprintf(buf, D_BUF, " . %s\n\t%s\n", + link->title, where); + else + snprintf(buf, D_BUF, " . %s\n", where); + } + + reflen = strlen(buf); + if (hard_write(fd, buf, reflen) != reflen) + return -1; + } + } + + return 0; +} + +int +dump_to_file(struct document *document, int fd) +{ + unsigned char *buf = mem_alloc(D_BUF); + int result; + + if (!buf) return -1; + + result = dump_nocolor(document, fd, buf); + if (!result) + result = dump_references(document, fd, buf); + + mem_free(buf); + return result; +} + +/* This dumps the given @cached's formatted output onto @fd. */ +static void +dump_formatted(int fd, struct download *download, struct cache_entry *cached) +{ + struct document_options o; + struct document_view formatted; + struct view_state vs; + int width; + unsigned char *buf; + + if (!cached) return; + + memset(&formatted, 0, sizeof(formatted)); + + init_document_options(&o); + width = get_opt_int("document.dump.width"); + set_box(&o.box, 0, 1, width, DEFAULT_TERMINAL_HEIGHT); + + o.cp = get_opt_codepage("document.dump.codepage"); + o.color_mode = get_opt_int("document.dump.color_mode"); + o.plain = 0; + o.frames = 0; + o.links_numbering = get_opt_bool("document.dump.numbering"); + + init_vs(&vs, cached->uri, -1); + + render_document(&vs, &formatted, &o); + + buf = mem_alloc(D_BUF); + if (buf) { + int result; + + switch (o.color_mode) { + case COLOR_MODE_DUMP: + case COLOR_MODE_MONO: /* FIXME: inversion */ + result = dump_nocolor(formatted.document, fd, buf); + break; + + default: + /* If the desired color mode was not compiled in, + * use 16 colors. */ + case COLOR_MODE_16: + result = dump_16color(formatted.document, fd, buf); + break; + +#ifdef CONFIG_88_COLORS + case COLOR_MODE_88: + result = dump_256color(formatted.document, fd, buf); + break; #endif +#ifdef CONFIG_256_COLORS + case COLOR_MODE_256: + result = dump_256color(formatted.document, fd, buf); + break; +#endif + +#ifdef CONFIG_TRUE_COLOR + case COLOR_MODE_TRUE_COLOR: + result = dump_truecolor(formatted.document, fd, buf); + break; +#endif + } + + if (!result) + dump_references(formatted.document, fd, buf); + + mem_free(buf); + } /* if buf */ + + detach_formatted(&formatted); + destroy_vs(&vs, 1); +} + +#undef D_BUF + /* This dumps the given @cached's source onto @fd nothing more. It returns 0 if it * all went fine and 1 if something isn't quite right and we should terminate * ourselves ASAP. */ @@ -101,64 +338,6 @@ nextfrag: return 0; } -/* This dumps the given @cached's formatted output onto @fd. */ -static void -dump_formatted(int fd, struct download *download, struct cache_entry *cached) -{ - struct document_options o; - struct document_view formatted; - struct view_state vs; - int width; - - if (!cached) return; - - memset(&formatted, 0, sizeof(formatted)); - - init_document_options(&o); - width = get_opt_int("document.dump.width"); - set_box(&o.box, 0, 1, width, DEFAULT_TERMINAL_HEIGHT); - - o.cp = get_opt_codepage("document.dump.codepage"); - o.color_mode = get_opt_int("document.dump.color_mode"); - o.plain = 0; - o.frames = 0; - o.links_numbering = get_opt_bool("document.dump.numbering"); - - init_vs(&vs, cached->uri, -1); - - render_document(&vs, &formatted, &o); - switch(o.color_mode) { - case COLOR_MODE_DUMP: - case COLOR_MODE_MONO: /* FIXME: inversion */ - dump_to_file(formatted.document, fd); - break; - default: - /* If the desired color mode was not compiled in, - * use 16 colors. */ - case COLOR_MODE_16: - dump_to_file_16(formatted.document, fd); - break; -#ifdef CONFIG_88_COLORS - case COLOR_MODE_88: - dump_to_file_256(formatted.document, fd); - break; -#endif -#ifdef CONFIG_256_COLORS - case COLOR_MODE_256: - dump_to_file_256(formatted.document, fd); - break; -#endif -#ifdef CONFIG_TRUE_COLOR - case COLOR_MODE_TRUE_COLOR: - dump_to_file_true_color(formatted.document, fd); - break; -#endif - } - - detach_formatted(&formatted); - destroy_vs(&vs, 1); -} - static unsigned char * subst_url(unsigned char *str, struct string *url) { @@ -435,134 +614,3 @@ end: #endif /* CONFIG_UTF8 */ return string; } - -#define D_BUF 65536 - -/*! @return 0 on success, -1 on error */ -static int -dump_references(struct document *document, int fd, unsigned char buf[D_BUF]) -{ - if (document->nlinks && get_opt_bool("document.dump.references")) { - int x; - unsigned char *header = "\nReferences\n\n Visible links\n"; - int headlen = strlen(header); - - if (hard_write(fd, header, headlen) != headlen) - return -1; - - for (x = 0; x < document->nlinks; x++) { - struct link *link = &document->links[x]; - unsigned char *where = link->where; - size_t reflen; - - if (!where) continue; - - if (document->options.links_numbering) { - if (link->title && *link->title) - snprintf(buf, D_BUF, "%4d. %s\n\t%s\n", - x + 1, link->title, where); - else - snprintf(buf, D_BUF, "%4d. %s\n", - x + 1, where); - } else { - if (link->title && *link->title) - snprintf(buf, D_BUF, " . %s\n\t%s\n", - link->title, where); - else - snprintf(buf, D_BUF, " . %s\n", where); - } - - reflen = strlen(buf); - if (hard_write(fd, buf, reflen) != reflen) - return -1; - } - } - - return 0; -} - -static int -write_char(unsigned char c, int fd, unsigned char *buf, int *bptr) -{ - buf[(*bptr)++] = c; - if ((*bptr) >= D_BUF) { - if (hard_write(fd, buf, (*bptr)) != (*bptr)) - return -1; - (*bptr) = 0; - } - - return 0; -} - -static int -write_color_16(unsigned char color, int fd, unsigned char *buf, int *bptr) -{ - unsigned char bufor[] = "\033[0;30;40m"; - unsigned char *data = bufor; - int background = (color >> 4) & 7; - int foreground = color & 7; - - bufor[5] += foreground; - if (background) bufor[8] += background; - else { - bufor[6] = 'm'; - bufor[7] = '\0'; - } - while(*data) { - if (write_char(*data++, fd, buf, bptr)) return -1; - } - return 0; -} - -#define DUMP_COLOR_MODE_16 -#include "dump-color-mode.h" -#undef DUMP_COLOR_MODE_16 - -/* configure --enable-debug uses gcc -Wall -Werror, and -Wall includes - * -Wunused-function, so declaring or defining any unused function - * would break the build. */ -#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) - -static int -write_color_256(unsigned char *str, unsigned char color, int fd, unsigned char *buf, int *bptr) -{ - unsigned char bufor[16]; - unsigned char *data = bufor; - - snprintf(bufor, 16, "\033[%s;5;%dm", str, color); - while(*data) { - if (write_char(*data++, fd, buf, bptr)) return -1; - } - return 0; -} - -#define DUMP_COLOR_MODE_256 -#include "dump-color-mode.h" -#undef DUMP_COLOR_MODE_256 - -#endif /* defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) */ - -#ifdef CONFIG_TRUE_COLOR - -static int -write_true_color(unsigned char *str, unsigned char *color, int fd, unsigned char *buf, int *bptr) -{ - unsigned char bufor[24]; - unsigned char *data = bufor; - - snprintf(bufor, 24, "\033[%s;2;%d;%d;%dm", str, color[0], color[1], color[2]); - while(*data) { - if (write_char(*data++, fd, buf, bptr)) return -1; - } - return 0; -} - -#define DUMP_COLOR_MODE_TRUE -#include "dump-color-mode.h" -#undef DUMP_COLOR_MODE_TRUE - -#endif /* CONFIG_TRUE_COLOR */ - -#include "dump-color-mode.h" - -#undef D_BUF