Changeset 5480:3e850c6e43fd

Show
Ignore:
Timestamp:
2008-08-19 00:39:44 (3 months ago)
Author:
Rocco Rutte <pdmef@…>
Branch:
HEAD
Message:

Make text/enriched handler multibyte aware. Closes #3033.

Files:
2 modified

Legend:

Unmodified
Added
Removed
  • handler.c

    r5437 r5480  
    450450struct enriched_state 
    451451{ 
    452   char *buffer; 
    453   char *line; 
    454   char *param; 
     452  wchar_t *buffer; 
     453  wchar_t *line; 
     454  wchar_t *param; 
    455455  size_t buff_len; 
    456456  size_t line_len; 
     
    467467}; 
    468468 
     469static int enriched_cmp (const char *a, const wchar_t *b) 
     470{ 
     471  register const char *p = a; 
     472  register const wchar_t *q = b; 
     473  int i; 
     474 
     475  if (!a && !b) 
     476    return 0; 
     477  if (!a && b) 
     478    return -1; 
     479  if (a && !b) 
     480    return 1; 
     481 
     482  for ( ; *p || *q; p++, q++) 
     483  { 
     484    if ((i = ascii_tolower (*p)) - ascii_tolower (((char) *q) & 0x7f)) 
     485      return i; 
     486  } 
     487  return 0; 
     488} 
     489 
    469490static void enriched_wrap (struct enriched_state *stte) 
    470491{ 
     
    479500      size_t y = stte->line_used - 1; 
    480501 
    481       while (y && ISSPACE (stte->line[y])) 
    482       { 
    483         stte->line[y] = '\0'; 
     502      while (y && iswspace (stte->line[y])) 
     503      { 
     504        stte->line[y] = (wchar_t) '\0'; 
    484505        y--; 
    485506        stte->line_used--; 
     
    491512        y = 0; 
    492513 
    493         while (stte->line[y] && ISSPACE (stte->line[y])) 
     514        while (stte->line[y] && iswspace (stte->line[y])) 
    494515          y++; 
    495516        if (y) 
     
    531552      } 
    532553    } 
    533     state_puts (stte->line, stte->s); 
     554    state_putws ((const wchar_t*) stte->line, stte->s); 
    534555  } 
    535556 
    536557  state_putc ('\n', stte->s); 
    537   stte->line[0] = '\0'; 
     558  stte->line[0] = (wchar_t) '\0'; 
    538559  stte->line_len = 0; 
    539560  stte->line_used = 0; 
     
    586607  if (stte->buff_used) 
    587608  { 
    588     stte->buffer[stte->buff_used] = '\0'; 
     609    stte->buffer[stte->buff_used] = (wchar_t) '\0'; 
    589610    stte->line_used += stte->buff_used; 
    590611    if (stte->line_used > stte->line_max) 
    591612    { 
    592613      stte->line_max = stte->line_used; 
    593       safe_realloc (&stte->line, stte->line_max + 1); 
    594     } 
    595     strcat (stte->line, stte->buffer);  /* __STRCAT_CHECKED__ */ 
     614      safe_realloc (&stte->line, (stte->line_max + 1) * sizeof (wchar_t)); 
     615    } 
     616    wcscat (stte->line, stte->buffer); 
    596617    stte->line_len += stte->word_len; 
    597618    stte->word_len = 0; 
     
    603624 
    604625 
    605 static void enriched_putc (int c, struct enriched_state *stte) 
     626static void enriched_putwc (wchar_t c, struct enriched_state *stte) 
    606627{ 
    607628  if (stte->tag_level[RICH_PARAM])  
     
    610631    { 
    611632      if (stte->param_used + 1 >= stte->param_len) 
    612         safe_realloc (&stte->param, (stte->param_len += STRING)); 
     633        safe_realloc (&stte->param, (stte->param_len += STRING) * sizeof (wchar_t)); 
    613634 
    614635      stte->param[stte->param_used++] = c; 
     
    621642  { 
    622643    stte->buff_len += LONG_STRING; 
    623     safe_realloc (&stte->buffer, stte->buff_len + 1); 
    624   } 
    625  
    626   if ((!stte->tag_level[RICH_NOFILL] && ISSPACE (c)) || c == '\0' ) 
    627   { 
    628     if (c == '\t') 
     644    safe_realloc (&stte->buffer, (stte->buff_len + 1) * sizeof (wchar_t)); 
     645  } 
     646 
     647  if ((!stte->tag_level[RICH_NOFILL] && iswspace (c)) || c == (wchar_t) '\0') 
     648  { 
     649    if (c == (wchar_t) '\t') 
    629650      stte->word_len += 8 - (stte->line_len + stte->word_len) % 8; 
    630651    else 
     
    641662      { 
    642663        stte->buffer[stte->buff_used++] = c; 
    643         stte->buffer[stte->buff_used++] = '\010'; 
     664        stte->buffer[stte->buff_used++] = (wchar_t) '\010'; 
    644665        stte->buffer[stte->buff_used++] = c; 
    645666      } 
     
    648669 
    649670        stte->buffer[stte->buff_used++] = '_'; 
    650         stte->buffer[stte->buff_used++] = '\010'; 
     671        stte->buffer[stte->buff_used++] = (wchar_t) '\010'; 
    651672        stte->buffer[stte->buff_used++] = c; 
    652673      } 
     
    654675      { 
    655676        stte->buffer[stte->buff_used++] = c; 
    656         stte->buffer[stte->buff_used++] = '\010'; 
     677        stte->buffer[stte->buff_used++] = (wchar_t) '\010'; 
    657678        stte->buffer[stte->buff_used++] = '_'; 
    658679      } 
     
    670691} 
    671692 
    672 static void enriched_puts (char *s, struct enriched_state *stte) 
    673 { 
    674   char *c; 
    675  
    676   if (stte->buff_len < stte->buff_used + mutt_strlen(s)) 
     693static void enriched_puts (const char *s, struct enriched_state *stte) 
     694{ 
     695  const char *c; 
     696 
     697  if (stte->buff_len < stte->buff_used + mutt_strlen (s)) 
    677698  { 
    678699    stte->buff_len += LONG_STRING; 
    679     safe_realloc (&stte->buffer, stte->buff_len + 1); 
     700    safe_realloc (&stte->buffer, (stte->buff_len + 1) * sizeof (wchar_t)); 
    680701  } 
    681702  c = s; 
    682703  while (*c) 
    683704  { 
    684     stte->buffer[stte->buff_used++] = *c; 
     705    stte->buffer[stte->buff_used++] = (wchar_t) *c; 
    685706    c++; 
    686707  } 
    687708} 
    688709 
    689 static void enriched_set_flags (const char *tag, struct enriched_state *stte) 
    690 { 
    691   const char *tagptr = tag; 
     710static void enriched_set_flags (const wchar_t *tag, struct enriched_state *stte) 
     711{ 
     712  const wchar_t *tagptr = tag; 
    692713  int i, j; 
    693714 
    694   if (*tagptr == '/') 
     715  if (*tagptr == (wchar_t) '/') 
    695716    tagptr++; 
    696717   
    697718  for (i = 0, j = -1; EnrichedTags[i].tag_name; i++) 
    698     if (ascii_strcasecmp (EnrichedTags[i].tag_name,tagptr) == 0) 
     719    if (enriched_cmp (EnrichedTags[i].tag_name, tagptr) == 0) 
    699720    { 
    700721      j = EnrichedTags[i].index; 
     
    707728      enriched_flush (stte, 1); 
    708729 
    709     if (*tag == '/') 
     730    if (*tag == (wchar_t) '/') 
    710731    { 
    711732      if (stte->tag_level[j]) /* make sure not to go negative */ 
     
    713734      if ((stte->s->flags & M_DISPLAY) && j == RICH_PARAM && stte->tag_level[RICH_COLOR]) 
    714735      { 
    715         stte->param[stte->param_used] = '\0'; 
    716         if (!ascii_strcasecmp(stte->param, "black")) 
     736        stte->param[stte->param_used] = (wchar_t) '\0'; 
     737        if (!enriched_cmp("black", stte->param)) 
    717738        { 
    718739          enriched_puts("\033[30m", stte); 
    719740        } 
    720         else if (!ascii_strcasecmp(stte->param, "red")) 
     741        else if (!enriched_cmp("red", stte->param)) 
    721742        { 
    722743          enriched_puts("\033[31m", stte); 
    723744        } 
    724         else if (!ascii_strcasecmp(stte->param, "green")) 
     745        else if (!enriched_cmp("green", stte->param)) 
    725746        { 
    726747          enriched_puts("\033[32m", stte); 
    727748        } 
    728         else if (!ascii_strcasecmp(stte->param, "yellow")) 
     749        else if (!enriched_cmp("yellow", stte->param)) 
    729750        { 
    730751          enriched_puts("\033[33m", stte); 
    731752        } 
    732         else if (!ascii_strcasecmp(stte->param, "blue")) 
     753        else if (!enriched_cmp("blue", stte->param)) 
    733754        { 
    734755          enriched_puts("\033[34m", stte); 
    735756        } 
    736         else if (!ascii_strcasecmp(stte->param, "magenta")) 
     757        else if (!enriched_cmp("magenta", stte->param)) 
    737758        { 
    738759          enriched_puts("\033[35m", stte); 
    739760        } 
    740         else if (!ascii_strcasecmp(stte->param, "cyan")) 
     761        else if (!enriched_cmp("cyan", stte->param)) 
    741762        { 
    742763          enriched_puts("\033[36m", stte); 
    743764        } 
    744         else if (!ascii_strcasecmp(stte->param, "white")) 
     765        else if (!enriched_cmp("white", stte->param)) 
    745766        { 
    746767          enriched_puts("\033[37m", stte); 
     
    756777      { 
    757778        stte->param_used = 0; 
    758         stte->param[0] = '\0'; 
     779        stte->param[0] = (wchar_t) '\0'; 
    759780      } 
    760781    } 
     
    775796  long bytes = a->length; 
    776797  struct enriched_state stte; 
    777   int c = 0; 
     798  wchar_t wc = 0; 
    778799  int tag_len = 0; 
    779   char tag[LONG_STRING + 1]; 
     800  wchar_t tag[LONG_STRING + 1]; 
    780801 
    781802  memset (&stte, 0, sizeof (stte)); 
     
    783804  stte.WrapMargin = ((s->flags & M_DISPLAY) ? (COLS-4) : ((COLS-4)<72)?(COLS-4):72); 
    784805  stte.line_max = stte.WrapMargin * 4; 
    785   stte.line = (char *) safe_calloc (1, stte.line_max + 1); 
    786   stte.param = (char *) safe_calloc (1, STRING); 
     806  stte.line = (wchar_t *) safe_calloc (1, (stte.line_max + 1) * sizeof (wchar_t)); 
     807  stte.param = (wchar_t *) safe_calloc (1, (STRING) * sizeof (wchar_t)); 
    787808 
    788809  stte.param_len = STRING; 
     
    799820    if (state != ST_EOF) 
    800821    { 
    801       if (!bytes || (c = fgetc (s->fpin)) == EOF) 
     822      if (!bytes || (wc = fgetwc (s->fpin)) == EOF) 
    802823        state = ST_EOF; 
    803824      else 
     
    808829    { 
    809830      case TEXT : 
    810         switch (c) 
     831        switch (wc) 
    811832        { 
    812833          case '<' : 
     
    821842            else  
    822843            { 
    823               enriched_putc (' ', &stte); 
     844              enriched_putwc ((wchar_t) ' ', &stte); 
    824845              state = NEWLINE; 
    825846            } 
     
    827848 
    828849          default: 
    829             enriched_putc (c, &stte); 
     850            enriched_putwc (wc, &stte); 
    830851        } 
    831852        break; 
    832853 
    833854      case LANGLE : 
    834         if (c == '<') 
    835         { 
    836           enriched_putc (c, &stte); 
     855        if (wc == (wchar_t) '<') 
     856        { 
     857          enriched_putwc (wc, &stte); 
    837858          state = TEXT; 
    838859          break; 
     
    845866        /* Yes, fall through (it wasn't a <<, so this char is first in TAG) */ 
    846867      case TAG : 
    847         if (c == '>') 
    848         { 
    849           tag[tag_len] = '\0'; 
     868        if (wc == (wchar_t) '>') 
     869        { 
     870          tag[tag_len] = (wchar_t) '\0'; 
    850871          enriched_set_flags (tag, &stte); 
    851872          state = TEXT; 
    852873        } 
    853874        else if (tag_len < LONG_STRING)  /* ignore overly long tags */ 
    854           tag[tag_len++] = c; 
     875          tag[tag_len++] = wc; 
    855876        else 
    856877          state = BOGUS_TAG; 
     
    858879 
    859880      case BOGUS_TAG : 
    860         if (c == '>') 
     881        if (wc == (wchar_t) '>') 
    861882          state = TEXT; 
    862883        break; 
    863884 
    864885      case NEWLINE : 
    865         if (c == '\n') 
     886        if (wc == (wchar_t) '\n') 
    866887          enriched_flush (&stte, 1); 
    867888        else 
    868889        { 
    869           ungetc (c, s->fpin); 
     890          ungetwc (wc, s->fpin); 
    870891          bytes++; 
    871892          state = TEXT; 
     
    874895 
    875896      case ST_EOF : 
    876         enriched_putc ('\0', &stte); 
     897        enriched_putwc ((wchar_t) '\0', &stte); 
    877898        enriched_flush (&stte, 1); 
    878899        state = DONE; 
  • mutt.h

    r5468 r5480  
    918918#define state_puts(x,y) fputs(x,(y)->fpout) 
    919919#define state_putc(x,y) fputc(x,(y)->fpout) 
     920#define state_putws(x,y) fputws(x,(y)->fpout) 
     921#define state_putwc(x,y) fputwc(x,(y)->fpout) 
    920922 
    921923void state_mark_attach (STATE *);