
#ifndef UTF8_H
#define UTF8_H

#include "def.h"
#include "argp.h"
#include "color.h"
#include <ctype.h>
#include <stddef.h>

/* This buffer size permits a full line of maximum-width utf-8
 * characters, plus a newline, a terminating null, and as many as two
 * colors.  */
#define UTF8_SIZE_BUF SIZE_UTF8*WIDTH_DATA+2+2*N_ESC+2*N_ESC0

char *utf8( char *out, size_t size_out, int n, ... );
void locale();

/* Lack of design elegance has a price.  The original program design
 * purposely traded elegance for execution speed in its byte-based text
 * handling (see datum.c).  Color output was soon added, grafted onto
 * the original fast design (see color.{h,c}).  This worked okay as far
 * as it went.  Unfortunately, the further addition of utf-8 handling
 * now leads to some slightly awkward code.  Architecturally speaking,
 * speed, color and Unicode interact somewhat unhappily within the
 * present design.  The code works correctly and still runs fairly
 * fast---especially, the new utf-8 does not significantly slow the old
 * Latin-1---but it promises some unpleasant labor to the future
 * programmer who wants to add significant new text-handling
 * features.  */

/* This function is defined only to ease the labored syntax of the
 * UTF82() macro.  (Neater ways of writing the macro may occur to the
 * reader, but because of the order in which CPP expands nested macros,
 * the neater ways may not actually work.)  This function probably
 * should be called for no other reason.  */
static inline char *utf8_sel_arg2(
  const int   i ,
  char *const s1,
  char *const s2
) { return i == 1 ? s1 : s2; }

#define UTF8(  S )                                       \
  opt.utf8 ? utf8( 0, 0, 1, S ) :                   S
#define UTF82( S )                                       \
  opt.utf8 ? utf8( 0, 0, 2, S ) : utf8_sel_arg2( 1, S ), \
  opt.utf8 ? ""                 : utf8_sel_arg2( 2, S )

/* Notice that these macros above call utf8(0, 0, ...), asking utf8() to
 * provide an output buffer.  For execution speed, utf8() maintains only
 * a fixed ring of SIZE_UTF8_RING buffers.  After so many calls to
 * utf8(), the function overwrites an old buffer; hence if the caller
 * wants to keep the buffer in the long term, it should not use these
 * macros but should provide its own buffer to utf8() directly.  (The
 * reason utf8() even keeps more than one buffer is so that several
 * calls to utf8() can be embedded in a single printf() statement.  The
 * several buffers are not meant for long-term storage.)
 *
 * Observe in argp.c that opt.no_latin1 (-L) quietly screens opt.utf8
 * (-u) and opt.latin1 (-l) out.  The user can ask for "-Lu" or "-Ll",
 * but really gets just "-L".
 *
 */

#endif

