1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-28 03:06:20 -04:00

bug 1080: Fold UTF-8 and unibyte dumping together

With all the comments and macros needed for this, the source files
don't become much shorter, but anyway I hope they'll be easier to
maintain this way.
This commit is contained in:
Kalle Olavi Niemitalo 2009-06-09 01:17:06 +03:00 committed by Kalle Olavi Niemitalo
parent 596a7cbd9b
commit 952c6fa8aa
3 changed files with 434 additions and 443 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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