~ubuntu-dev/ubuntu/lucid/mutt/lucid-201002110857

« back to all changes in this revision

Viewing changes to pager.c

  • Committer: Bazaar Package Importer
  • Author(s): أحمد المحمودي (Ahmed El-Mahmoudy)
  • Date: 2009-06-17 17:17:28 UTC
  • mfrom: (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20090617171728-61dkl7w5fgn7ybdq
Tags: upstream-1.5.20
Import upstream version 1.5.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
812
812
  if (lineInfo[n].type == MT_COLOR_NORMAL || 
813
813
      lineInfo[n].type == MT_COLOR_QUOTED)
814
814
  {
 
815
    size_t nl;
 
816
 
 
817
    /* don't consider line endings part of the buffer
 
818
     * for regex matching */
 
819
    if ((nl = mutt_strlen (buf)) > 0 && buf[nl-1] == '\n')
 
820
      buf[nl-1] = 0;
 
821
 
815
822
    i = 0;
816
 
 
817
823
    offset = 0;
818
824
    lineInfo[n].chunks = 0;
819
825
    do
863
869
      else
864
870
        offset = (lineInfo[n].syntax)[i].last;
865
871
    } while (found || null_rx);
 
872
    if (nl > 0)
 
873
      buf[nl] = '\n';
866
874
  }
867
875
}
868
876
 
988
996
}
989
997
 
990
998
static int
991
 
fill_buffer (FILE *f, LOFF_T *last_pos, LOFF_T offset, unsigned char *buf, 
992
 
             unsigned char *fmt, size_t blen, int *buf_ready)
 
999
fill_buffer (FILE *f, LOFF_T *last_pos, LOFF_T offset, unsigned char **buf,
 
1000
             unsigned char **fmt, size_t *blen, int *buf_ready)
993
1001
{
994
 
  unsigned char *p;
 
1002
  unsigned char *p, *q;
995
1003
  static int b_read;
996
 
  
 
1004
  int l;
 
1005
 
997
1006
  if (*buf_ready == 0)
998
1007
  {
999
 
    buf[blen - 1] = 0;
1000
1008
    if (offset != *last_pos)
1001
1009
      fseeko (f, offset, 0);
1002
 
    if (fgets ((char *) buf, blen - 1, f) == NULL)
 
1010
    if ((*buf = (unsigned char *) mutt_read_line ((char *) *buf, blen, f, &l, M_EOL)) == NULL)
1003
1011
    {
1004
1012
      fmt[0] = 0;
1005
1013
      return (-1);
1008
1016
    b_read = (int) (*last_pos - offset);
1009
1017
    *buf_ready = 1;
1010
1018
 
 
1019
    safe_realloc (fmt, *blen);
 
1020
 
1011
1021
    /* incomplete mbyte characters trigger a segfault in regex processing for
1012
1022
     * certain versions of glibc. Trim them if necessary. */
1013
 
    if (b_read == blen - 2)
1014
 
      b_read -= trim_incomplete_mbyte(buf, b_read);
 
1023
    if (b_read == *blen - 2)
 
1024
      b_read -= trim_incomplete_mbyte(*buf, b_read);
1015
1025
    
1016
1026
    /* copy "buf" to "fmt", but without bold and underline controls */
1017
 
    p = buf;
 
1027
    p = *buf;
 
1028
    q = *fmt;
1018
1029
    while (*p)
1019
1030
    {
1020
 
      if (*p == '\010' && (p > buf))
 
1031
      if (*p == '\010' && (p > *buf))
1021
1032
      {
1022
1033
        if (*(p+1) == '_')      /* underline */
1023
1034
          p += 2;
1024
1035
        else if (*(p+1))        /* bold or overstrike */
1025
1036
        {
1026
 
          *(fmt-1) = *(p+1);
 
1037
          *(q-1) = *(p+1);
1027
1038
          p += 2;
1028
1039
        }
1029
1040
        else                    /* ^H */
1030
 
          *fmt++ = *p++;
 
1041
          *q++ = *p++;
1031
1042
      }
1032
1043
      else if (*p == '\033' && *(p+1) == '[' && is_ansi (p + 2))
1033
1044
      {
1041
1052
          ;
1042
1053
      }
1043
1054
      else
1044
 
        *fmt++ = *p++;
 
1055
        *q++ = *p++;
1045
1056
    }
1046
 
    *fmt = 0;
 
1057
    *q = 0;
1047
1058
  }
1048
1059
  return b_read;
1049
1060
}
1228
1239
              int *last, int *max, int flags, struct q_class_t **QuoteList,
1229
1240
              int *q_level, int *force_redraw, regex_t *SearchRE)
1230
1241
{
1231
 
  unsigned char buf[LONG_STRING], fmt[LONG_STRING];
 
1242
  unsigned char *buf = NULL, *fmt = NULL;
 
1243
  size_t buflen = 0;
1232
1244
  unsigned char *buf_ptr = buf;
1233
1245
  int ch, vch, col, cnt, b_read;
1234
1246
  int buf_ready = 0, change_last = 0;
1236
1248
  int offset;
1237
1249
  int def_color;
1238
1250
  int m;
 
1251
  int rc = -1;
1239
1252
  ansi_attr a = {0,0,0,-1};
1240
1253
  regmatch_t pmatch[1];
1241
1254
 
1264
1277
    if ((*lineInfo)[n].type == -1)
1265
1278
    {
1266
1279
      /* determine the line class */
1267
 
      if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, sizeof (buf), &buf_ready) < 0)
 
1280
      if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1268
1281
      {
1269
1282
        if (change_last)
1270
1283
          (*last)--;
1271
 
        return (-1);
 
1284
        goto out;
1272
1285
      }
1273
1286
 
1274
1287
      resolve_types ((char *) fmt, (char *) buf, *lineInfo, n, *last,
1293
1306
  if ((flags & M_SHOWCOLOR) && !(*lineInfo)[n].continuation &&
1294
1307
      (*lineInfo)[n].type == MT_COLOR_QUOTED && (*lineInfo)[n].quote == NULL)
1295
1308
  {
1296
 
    if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, sizeof (buf), &buf_ready) < 0)
 
1309
    if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1297
1310
    {
1298
1311
      if (change_last)
1299
1312
        (*last)--;
1300
 
      return (-1);
 
1313
      goto out;
1301
1314
    }
1302
1315
    regexec ((regex_t *) QuoteRegexp.rx, (char *) fmt, 1, pmatch, 0);
1303
1316
    (*lineInfo)[n].quote = classify_quote (QuoteList,
1308
1321
 
1309
1322
  if ((flags & M_SEARCH) && !(*lineInfo)[n].continuation && (*lineInfo)[n].search_cnt == -1) 
1310
1323
  {
1311
 
    if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, sizeof (buf), &buf_ready) < 0)
 
1324
    if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1312
1325
    {
1313
1326
      if (change_last)
1314
1327
        (*last)--;
1315
 
      return (-1);
 
1328
      goto out;
1316
1329
    }
1317
1330
 
1318
1331
    offset = 0;
1341
1354
  if (!(flags & M_SHOW) && (*lineInfo)[n+1].offset > 0)
1342
1355
  {
1343
1356
    /* we've already scanned this line, so just exit */
1344
 
    return (0);
 
1357
    rc = 0;
 
1358
    goto out;
1345
1359
  }
1346
1360
  if ((flags & M_SHOWCOLOR) && *force_redraw && (*lineInfo)[n+1].offset > 0)
1347
1361
  {
1348
1362
    /* no need to try to display this line... */
1349
 
    return (1); /* fake display */
 
1363
    rc = 1;
 
1364
    goto out; /* fake display */
1350
1365
  }
1351
1366
 
1352
 
  if ((b_read = fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, 
1353
 
                              sizeof (buf), &buf_ready)) < 0)
 
1367
  if ((b_read = fill_buffer (f, last_pos, (*lineInfo)[n].offset, &buf, &fmt, 
 
1368
                             &buflen, &buf_ready)) < 0)
1354
1369
  {
1355
1370
    if (change_last)
1356
1371
      (*last)--;
1357
 
    return (-1);
 
1372
    goto out;
1358
1373
  }
1359
1374
 
1360
1375
  /* now chose a good place to break the line */
1398
1413
 
1399
1414
  /* if we don't need to display the line we are done */
1400
1415
  if (!(flags & M_SHOW))
1401
 
    return 0;
 
1416
  {
 
1417
    rc = 0;
 
1418
    goto out;
 
1419
  }
1402
1420
 
1403
1421
  /* display the line */
1404
1422
  format_line (lineInfo, n, buf, flags, &a, cnt, &ch, &vch, &col, &special);
1459
1477
  if (!(flags & M_SHOW))
1460
1478
    flags = 0;
1461
1479
 
1462
 
  return (flags);
 
1480
  rc = flags;
 
1481
 
 
1482
out:
 
1483
  FREE(&buf);
 
1484
  FREE(&fmt);
 
1485
  return rc;
1463
1486
}
1464
1487
 
1465
1488
static int
1499
1522
int 
1500
1523
mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
1501
1524
{
1502
 
  static char searchbuf[STRING];
 
1525
  static char searchbuf[STRING] = "";
1503
1526
  char buffer[LONG_STRING];
1504
1527
  char helpstr[SHORT_STRING*2];
1505
1528
  char tmphelp[SHORT_STRING*2];
1508
1531
  struct q_class_t *QuoteList = NULL;
1509
1532
  int i, j, ch = 0, rc = -1, hideQuoted = 0, q_level = 0, force_redraw = 0;
1510
1533
  int lines = 0, curline = 0, topline = 0, oldtopline = 0, err, first = 1;
1511
 
  int r = -1, wrapped = 0;
 
1534
  int r = -1, wrapped = 0, searchctx = 0;
1512
1535
  int redraw = REDRAW_FULL;
1513
1536
  FILE *fp = NULL;
1514
1537
  LOFF_T last_pos = 0, last_offset = 0;
1542
1565
  if (stat (fname, &sb) != 0)
1543
1566
  {
1544
1567
    mutt_perror (fname);
1545
 
    fclose (fp);
 
1568
    safe_fclose (&fp);
1546
1569
    return (-1);
1547
1570
  }
1548
1571
  unlink (fname);
1744
1767
      SETCOLOR (MT_COLOR_STATUS);
1745
1768
      BKGDSET (MT_COLOR_STATUS);
1746
1769
      CLEARLINE (statusoffset);
1747
 
      if (IsHeader (extra))
1748
 
      {
1749
 
        size_t l1 = COLS * MB_LEN_MAX;
1750
 
        size_t l2 = sizeof (buffer);
1751
 
        hfi.hdr = extra->hdr;
1752
 
        mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
1753
 
      }
1754
 
      else if (IsMsgAttach (extra))
1755
 
      {
1756
 
        size_t l1 = COLS * MB_LEN_MAX;
1757
 
        size_t l2 = sizeof (buffer);
1758
 
        hfi.hdr = extra->bdy->hdr;
1759
 
        mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
1760
 
      }
1761
 
      mutt_paddstr (COLS, IsHeader (extra) || IsMsgAttach (extra) ?  buffer : banner);
 
1770
 
 
1771
      if (IsHeader (extra) || IsMsgAttach (extra))
 
1772
      {
 
1773
        size_t l1 = COLS * MB_LEN_MAX;
 
1774
        size_t l2 = sizeof (buffer);
 
1775
        hfi.hdr = (IsHeader (extra)) ? extra->hdr : extra->bdy->hdr;
 
1776
        mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
 
1777
        mutt_paddstr (COLS, buffer);
 
1778
      }
 
1779
      else
 
1780
      {
 
1781
        char bn[STRING];
 
1782
        snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
 
1783
        mutt_paddstr (COLS, bn);
 
1784
      }
1762
1785
      BKGDSET (MT_COLOR_NORMAL);
1763
1786
      SETCOLOR (MT_COLOR_NORMAL);
1764
1787
    }
1965
1988
        {
1966
1989
          wrapped = 0;
1967
1990
 
 
1991
          if (SearchContext > 0 && SearchContext < LINES - 2 - option (OPTHELP) ? 1 : 0)
 
1992
            searchctx = SearchContext;
 
1993
          else
 
1994
            searchctx = 0;
 
1995
 
1968
1996
search_next:
1969
1997
          if ((!SearchBack && ch==OP_SEARCH_NEXT) ||
1970
1998
              (SearchBack &&ch==OP_SEARCH_OPPOSITE))
1971
1999
          {
1972
2000
            /* searching forward */
1973
 
            for (i = wrapped ? 0 : topline + 1; i < lastLine; i++)
 
2001
            for (i = wrapped ? 0 : topline + searchctx + 1; i < lastLine; i++)
1974
2002
            {
1975
2003
              if ((!hideQuoted || lineInfo[i].type != MT_COLOR_QUOTED) && 
1976
2004
                    !lineInfo[i].continuation && lineInfo[i].search_cnt > 0)
1991
2019
          else
1992
2020
          {
1993
2021
            /* searching backward */
1994
 
            for (i = wrapped ? lastLine : topline - 1; i >= 0; i--)
 
2022
            for (i = wrapped ? lastLine : topline + searchctx - 1; i >= 0; i--)
1995
2023
            {
1996
2024
              if ((!hideQuoted || (has_types && 
1997
2025
                    lineInfo[i].type != MT_COLOR_QUOTED)) && 
2012
2040
          }
2013
2041
 
2014
2042
          if (lineInfo[topline].search_cnt > 0)
 
2043
          {
2015
2044
            SearchFlag = M_SEARCH;
 
2045
            /* give some context for search results */
 
2046
            if (topline - searchctx > 0)
 
2047
              topline -= searchctx;
 
2048
          }
2016
2049
 
2017
2050
          break;
2018
2051
        }
2021
2054
      case OP_SEARCH:
2022
2055
      case OP_SEARCH_REVERSE:
2023
2056
        strfcpy (buffer, searchbuf, sizeof (buffer));
2024
 
        if (mutt_get_field ((SearchBack ? _("Reverse search: ") :
2025
 
                          _("Search: ")), buffer, sizeof (buffer),
2026
 
                          M_CLEAR) != 0)
 
2057
        if (mutt_get_field ((ch == OP_SEARCH || ch == OP_SEARCH_NEXT) ?
 
2058
                            _("Search for: ") : _("Reverse search for: "),
 
2059
                            buffer, sizeof (buffer),
 
2060
                            M_CLEAR) != 0)
2027
2061
          break;
2028
2062
 
2029
2063
        if (!strcmp (buffer, searchbuf))
2120
2154
            mutt_error _("Not found.");
2121
2155
          }
2122
2156
          else
 
2157
          {
2123
2158
            SearchFlag = M_SEARCH;
 
2159
            /* give some context for search results */
 
2160
            if (SearchContext > 0 && SearchContext < LINES - 2 - option (OPTHELP) ? 1 : 0)
 
2161
              searchctx = SearchContext;
 
2162
            else
 
2163
              searchctx = 0;
 
2164
            if (topline - searchctx > 0)
 
2165
              topline -= searchctx;
 
2166
          }
 
2167
 
2124
2168
        }
2125
2169
        redraw = REDRAW_BODY;
2126
2170
        break;
2281
2325
        }
2282
2326
        break;
2283
2327
 
 
2328
      case OP_MAIN_SET_FLAG:
 
2329
      case OP_MAIN_CLEAR_FLAG:
 
2330
        CHECK_MODE(IsHeader (extra));
 
2331
        CHECK_READONLY;
 
2332
 
 
2333
        if (mutt_change_flag (extra->hdr, (ch == OP_MAIN_SET_FLAG)) == 0)
 
2334
          redraw |= REDRAW_STATUS | REDRAW_INDEX;
 
2335
        if (extra->hdr->deleted && option (OPTRESOLVE))
 
2336
        {
 
2337
          ch = -1;
 
2338
          rc = OP_MAIN_NEXT_UNDELETED;
 
2339
        }
 
2340
        break;
 
2341
 
2284
2342
      case OP_DELETE_THREAD:
2285
2343
      case OP_DELETE_SUBTHREAD:
2286
2344
        CHECK_MODE(IsHeader (extra));
2677
2735
    }
2678
2736
  }
2679
2737
 
2680
 
  fclose (fp);
 
2738
  safe_fclose (&fp);
2681
2739
  if (IsHeader (extra))
2682
2740
  {
2683
2741
    Context->msgnotreadyet = -1;