~kevin8t8/mutt

0ac6b609cd9e4588f00221b5c66e0fd5f584da88 — Kevin McCarthy 3 days ago c44f0ce
Refactor mutt_buffer_strip_formatting() inside of pager.c.

Rather than duplicate the logic, move the function back inside
pager.c.  Add a parameter to optionally remove attachment markers.

Inside fill_buffer(), use a stack-based buffer and directly assign the
buffer.data back to fmt, to keep it as fast as before.
5 files changed, 66 insertions(+), 90 deletions(-)

M handler.c
M muttlib.c
M pager.c
M pager.h
M protos.h
M handler.c => handler.c +2 -1
@@ 36,6 36,7 @@
#include "charset.h"
#include "mutt_crypt.h"
#include "rfc3676.h"
#include "pager.h"

#define BUFI_SIZE 1000
#define BUFO_SIZE 2000


@@ 1386,7 1387,7 @@ static int autoview_handler (BODY *a, STATE *s)
      BUFFER *stripped = mutt_buffer_pool_get ();
      while (fgets (buffer, sizeof(buffer), fpout) != NULL)
      {
        mutt_buffer_strip_formatting (stripped, buffer);
        mutt_buffer_strip_formatting (stripped, buffer, 0);
        state_puts (s->prefix, s);
        state_puts (mutt_b2s (stripped), s);
      }

M muttlib.c => muttlib.c +0 -46
@@ 1139,52 1139,6 @@ void mutt_buffer_sanitize_filename (BUFFER *d, const char *f, short slash)
  }
}

static int is_ansi (const char *buf)
{
  while (*buf && (isdigit(*buf) || *buf == ';'))
    buf++;
  return (*buf == 'm');
}

/* Removes ANSI and backspace formatting.
 *
 * This logic is pulled from the pager fill_buffer() function, for use
 * in stripping reply-quoted autoview output of ansi sequences.
 */
void mutt_buffer_strip_formatting (BUFFER *dest, const char *src)
{
  const char *s = src;

  mutt_buffer_clear (dest);

  if (!s)
    return;

  while (*s)
  {
    if (*s == '\010' && (s > src))
    {
      if (*(s+1) == '_')	/* underline */
        s += 2;
      else if (*(s+1) && mutt_buffer_len (dest))	/* bold or overstrike */
      {
        dest->dptr--;
        mutt_buffer_addch (dest, *(s+1));
        s += 2;
      }
      else			/* ^H */
        mutt_buffer_addch (dest, *s++);
    }
    else if (*s == '\033' && *(s+1) == '[' && is_ansi (s + 2))
    {
      while (*s++ != 'm')	/* skip ANSI sequence */
        ;
    }
    else
      mutt_buffer_addch (dest, *s++);
  }
}

void mutt_expand_file_fmt (BUFFER *dest, const char *fmt, const char *src)
{
  BUFFER *tmp;

M pager.c => pager.c +63 -42
@@ 952,7 952,7 @@ resolve_types (char *buf, char *raw, struct line_t *lineInfo, int n, int last,
  }
}

static int is_ansi (unsigned char *buf)
static int is_ansi (const char *buf)
{
  while (*buf && (isdigit(*buf) || *buf == ';'))
    buf++;


@@ 1060,64 1060,85 @@ static int grok_ansi(unsigned char *buf, int pos, ansi_attr *a)
  return pos;
}

/* Removes ANSI and backspace formatting, and optionally markers.
 *
 * This is separated out so that it can be used both by the pager
 * and the autoview handler.
 */
void mutt_buffer_strip_formatting (BUFFER *dest, const char *src, int strip_markers)
{
  const char *s = src;

  mutt_buffer_clear (dest);

  if (!s)
    return;

  while (*s)
  {
    if (*s == '\010' && (s > src))
    {
      if (*(s+1) == '_')	/* underline */
        s += 2;
      else if (*(s+1) && mutt_buffer_len (dest))	/* bold or overstrike */
      {
        dest->dptr--;
        mutt_buffer_addch (dest, *(s+1));
        s += 2;
      }
      else			/* ^H */
        mutt_buffer_addch (dest, *s++);
    }
    else if (*s == '\033' && *(s+1) == '[' && is_ansi (s + 2))
    {
      while (*s++ != 'm')	/* skip ANSI sequence */
        ;
    }
    else if (strip_markers &&
             *s == '\033' && *(s+1) == ']' &&
             ((check_attachment_marker (s) == 0) ||
              (check_protected_header_marker (s) == 0)))
    {
      dprint (2, (debugfile, "mutt_buffer_strip_formatting: Seen attachment marker.\n"));
      while (*s++ != '\a')	/* skip pseudo-ANSI sequence */
        ;
    }
    else
      mutt_buffer_addch (dest, *s++);
  }
}

static int
fill_buffer (FILE *f, LOFF_T *last_pos, LOFF_T offset, unsigned char **buf,
	     unsigned char **fmt, size_t *blen, int *buf_ready)
{
  unsigned char *p, *q;
  static int b_read;
  int l;
  BUFFER stripped;

  if (*buf_ready == 0)
  {
    if (offset != *last_pos)
      fseeko (f, offset, 0);
    if ((*buf = (unsigned char *) mutt_read_line ((char *) *buf, blen, f, &l, MUTT_EOL)) == NULL)

    if ((*buf = (unsigned char *) mutt_read_line ((char *) *buf, blen, f,
                                                  NULL, MUTT_EOL)) == NULL)
    {
      fmt[0] = 0;
      *fmt = NULL;
      return (-1);
    }

    *last_pos = ftello (f);
    b_read = (int) (*last_pos - offset);
    *buf_ready = 1;

    safe_realloc (fmt, *blen);

    /* copy "buf" to "fmt", but without bold and underline controls */
    p = *buf;
    q = *fmt;
    while (*p)
    {
      if (*p == '\010' && (p > *buf))
      {
	if (*(p+1) == '_')	/* underline */
	  p += 2;
	else if (*(p+1) && q > *fmt)	/* bold or overstrike */
	{
	  *(q-1) = *(p+1);
	  p += 2;
	}
	else			/* ^H */
	  *q++ = *p++;
      }
      else if (*p == '\033' && *(p+1) == '[' && is_ansi (p + 2))
      {
	while (*p++ != 'm')	/* skip ANSI sequence */
	  ;
      }
      else if (*p == '\033' && *(p+1) == ']' &&
               ((check_attachment_marker ((char *) p) == 0) ||
                (check_protected_header_marker ((char *) p) == 0)))
      {
	dprint (2, (debugfile, "fill_buffer: Seen attachment marker.\n"));
	while (*p++ != '\a')	/* skip pseudo-ANSI sequence */
	  ;
      }
      else
	*q++ = *p++;
    }
    *q = 0;
    mutt_buffer_init (&stripped);
    mutt_buffer_increase_size (&stripped, *blen);
    mutt_buffer_strip_formatting (&stripped, (const char *) *buf, 1);
    /* This should be a noop, because *fmt should be NULL */
    FREE (fmt);   /* __FREE_CHECKED__ */
    *fmt = (unsigned char *) stripped.data;
  }

  return b_read;
}



@@ 1145,7 1166,7 @@ static int format_line (struct line_t **lineInfo, int n, unsigned char *buf,
  {
    /* Handle ANSI sequences */
    while (cnt-ch >= 2 && buf[ch] == '\033' && buf[ch+1] == '[' &&
	   is_ansi (buf+ch+2))
	   is_ansi ((char *) buf+ch+2))
      ch = grok_ansi (buf, ch+2, pa) + 1;

    while (cnt-ch >= 2 && buf[ch] == '\033' && buf[ch+1] == ']' &&

M pager.h => pager.h +1 -0
@@ 47,3 47,4 @@ typedef struct

int mutt_do_pager (const char *, const char *, int, pager_t *);
int mutt_pager (const char *, const char *, int, pager_t *);
void mutt_buffer_strip_formatting (BUFFER *dest, const char *src, int strip_markers);

M protos.h => protos.h +0 -1
@@ 179,7 179,6 @@ void mutt_buffer_concatn_path (BUFFER *dst, const char *dir, size_t dirlen,
#define mutt_buffer_quote_filename(a,b) _mutt_buffer_quote_filename (a, b, 1);
void _mutt_buffer_quote_filename (BUFFER *, const char *, int);
void mutt_buffer_sanitize_filename (BUFFER *d, const char *f, short slash);
void mutt_buffer_strip_formatting (BUFFER *dest, const char *src);
void mutt_canonical_charset (char *, size_t, const char *);
void mutt_check_stats(void);
int mutt_count_body_parts (CONTEXT *, HEADER *);