~ubuntu-branches/ubuntu/utopic/coreutils/utopic-proposed

« back to all changes in this revision

Viewing changes to src/ptx.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-11-28 03:03:42 UTC
  • mfrom: (8.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20121128030342-21zanj8354gas5gr
Tags: 8.20-3ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Make 'uname -i -p' return the real processor/hardware, instead of
    unknown.
  - Build-depend on gettext:any instead of on gettext, so that apt-get can
    properly resolve build-dependencies on the tool when cross-building.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Permuted index for GNU, with keywords in their context.
2
 
   Copyright (C) 1990-1991, 1993, 1998-2011 Free Software Foundation, Inc.
 
2
   Copyright (C) 1990-2012 Free Software Foundation, Inc.
3
3
   François Pinard <pinard@iro.umontreal.ca>, 1988.
4
4
 
5
5
   This program is free software: you can redistribute it and/or modify
33
33
#include "stdio--.h"
34
34
#include "xstrtol.h"
35
35
 
36
 
/* The official name of this program (e.g., no `g' prefix).  */
 
36
/* The official name of this program (e.g., no 'g' prefix).  */
37
37
#define PROGRAM_NAME "ptx"
38
38
 
39
39
/* TRANSLATORS: Please translate "F. Pinard" to "François Pinard"
69
69
{
70
70
  UNKNOWN_FORMAT,               /* output format still unknown */
71
71
  DUMB_FORMAT,                  /* output for a dumb terminal */
72
 
  ROFF_FORMAT,                  /* output for `troff' or `nroff' */
73
 
  TEX_FORMAT                    /* output for `TeX' or `LaTeX' */
 
72
  ROFF_FORMAT,                  /* output for 'troff' or 'nroff' */
 
73
  TEX_FORMAT                    /* output for 'TeX' or 'LaTeX' */
74
74
};
75
75
 
76
76
static bool gnu_extensions = true;      /* trigger all GNU extensions */
77
 
static bool auto_reference = false;     /* refs are `file_name:line_number:' */
 
77
static bool auto_reference = false;     /* refs are 'file_name:line_number:' */
78
78
static bool input_reference = false;    /* refs at beginning of input lines */
79
79
static bool right_reference = false;    /* output refs after right context  */
80
80
static int line_width = 72;     /* output line width in characters */
86
86
                                /* output format */
87
87
 
88
88
static bool ignore_case = false;        /* fold lower to upper for sorting */
89
 
static const char *break_file = NULL;   /* name of the `Break chars' file */
90
 
static const char *only_file = NULL;    /* name of the `Only words' file */
91
 
static const char *ignore_file = NULL;  /* name of the `Ignore words' file */
 
89
static const char *break_file = NULL;   /* name of the 'Break chars' file */
 
90
static const char *only_file = NULL;    /* name of the 'Only words' file */
 
91
static const char *ignore_file = NULL;  /* name of the 'Ignore words' file */
92
92
 
93
93
/* Options that use regular expressions.  */
94
94
struct regex_data
164
164
static int number_input_files;  /* number of text input files */
165
165
static int total_line_count;    /* total number of lines seen so far */
166
166
static const char **input_file_name;    /* array of text input file names */
167
 
static int *file_line_count;    /* array of `total_line_count' values at end */
 
167
static int *file_line_count;    /* array of 'total_line_count' values at end */
168
168
 
169
169
static BLOCK text_buffer;       /* file to study */
170
170
 
199
199
 
200
200
/* Occurrences table.
201
201
 
202
 
   The `keyword' pointer provides the central word, which is surrounded
203
 
   by a left context and a right context.  The `keyword' and `length'
 
202
   The 'keyword' pointer provides the central word, which is surrounded
 
203
   by a left context and a right context.  The 'keyword' and 'length'
204
204
   field allow full 8-bit characters keys, even including NULs.  At other
205
 
   places in this program, the name `keyafter' refers to the keyword
 
205
   places in this program, the name 'keyafter' refers to the keyword
206
206
   followed by its right context.
207
207
 
208
208
   The left context does not extend, towards the beginning of the file,
209
 
   further than a distance given by the `left' value.  This value is
 
209
   further than a distance given by the 'left' value.  This value is
210
210
   relative to the keyword beginning, it is usually negative.  This
211
211
   insures that, except for white space, we will never have to backward
212
212
   scan the source text, when it is time to generate the final output
214
214
 
215
215
   The right context, indirectly attainable through the keyword end, does
216
216
   not extend, towards the end of the file, further than a distance given
217
 
   by the `right' value.  This value is relative to the keyword
 
217
   by the 'right' value.  This value is relative to the keyword
218
218
   beginning, it is usually positive.
219
219
 
220
 
   When automatic references are used, the `reference' value is the
 
220
   When automatic references are used, the 'reference' value is the
221
221
   overall line number in all input files read so far, in this case, it
222
 
   is of type (int).  When input references are used, the `reference'
 
222
   is of type (int).  When input references are used, the 'reference'
223
223
   value indicates the distance between the keyword beginning and the
224
224
   start of the reference field, it is of type (DELTA) and usually
225
225
   negative.  */
254
254
static int truncation_string_length;/* length of string that flags truncation */
255
255
 
256
256
/* When context is limited by lines, wraparound may happen on final output:
257
 
   the `head' pointer gives access to some supplementary left context which
258
 
   will be seen at the end of the output line, the `tail' pointer gives
 
257
   the 'head' pointer gives access to some supplementary left context which
 
258
   will be seen at the end of the output line, the 'tail' pointer gives
259
259
   access to some supplementary right context which will be seen at the
260
260
   beginning of the output line. */
261
261
 
418
418
  if (message)
419
419
    error (EXIT_FAILURE, 0, _("%s (for regexp %s)"), message, quote (string));
420
420
 
421
 
  /* The fastmap should be compiled before `re_match'.  The following
422
 
     call is not mandatory, because `re_search' is always called sooner,
 
421
  /* The fastmap should be compiled before 're_match'.  The following
 
422
     call is not mandatory, because 're_search' is always called sooner,
423
423
     and it compiles the fastmap if this has not been done yet.  */
424
424
 
425
425
  re_compile_fastmap (pattern);
620
620
}
621
621
 
622
622
/*---------------------------------------------------------------------.
623
 
| Sort the whole occurs table in memory.  Presumably, `qsort' does not |
 
623
| Sort the whole occurs table in memory.  Presumably, 'qsort' does not |
624
624
| take intermediate copies or table elements, so the sort will be      |
625
625
| stabilized throughout the comparison routine.                        |
626
626
`---------------------------------------------------------------------*/
760
760
  char *word_end;               /* end of word */
761
761
  char *next_context_start;     /* next start of left context */
762
762
 
763
 
  /* reference_length is always used within `if (input_reference)'.
 
763
  /* reference_length is always used within 'if (input_reference)'.
764
764
     However, GNU C diagnoses that it may be used uninitialized.  The
765
765
     following assignment is merely to shut it up.  */
766
766
 
791
791
       cursor = next_context_start)
792
792
    {
793
793
 
794
 
      /* `context_start' gets initialized before the processing of each
 
794
      /* 'context_start' gets initialized before the processing of each
795
795
         line, or once for the whole buffer if no end of line or sentence
796
796
         sequence separator.  */
797
797
 
798
798
      context_start = cursor;
799
799
 
800
800
      /* If an end of line or end of sentence sequence is defined and
801
 
         non-empty, `next_context_start' will be recomputed to be the end of
 
801
         non-empty, 'next_context_start' will be recomputed to be the end of
802
802
         each line or sentence, before each one is processed.  If no such
803
 
         sequence, then `next_context_start' is set at the end of the whole
 
803
         sequence, then 'next_context_start' is set at the end of the whole
804
804
         buffer, which is then considered to be a single line or sentence.
805
805
         This test also accounts for the case of an incomplete line or
806
806
         sentence at the end of the buffer.  */
902
902
          if (possible_key.size > maximum_word_length)
903
903
            maximum_word_length = possible_key.size;
904
904
 
905
 
          /* In input reference mode, update `line_start' from its previous
 
905
          /* In input reference mode, update 'line_start' from its previous
906
906
             value.  Count the lines just in case auto reference mode is
907
907
             also selected. If it happens that the word just matched is
908
908
             indeed part of a reference; just ignore it.  */
924
924
                continue;
925
925
            }
926
926
 
927
 
          /* Ignore the word if an `Ignore words' table exists and if it is
928
 
             part of it.  Also ignore the word if an `Only words' table and
 
927
          /* Ignore the word if an 'Ignore words' table exists and if it is
 
928
             part of it.  Also ignore the word if an 'Only words' table and
929
929
             if it is *not* part of it.
930
930
 
931
931
             It is allowed that both tables be used at once, even if this
961
961
          if (auto_reference)
962
962
            {
963
963
 
964
 
              /* While auto referencing, update `line_start' from its
 
964
              /* While auto referencing, update 'line_start' from its
965
965
                 previous value, counting lines as we go.  If input
966
 
                 referencing at the same time, `line_start' has been
 
966
                 referencing at the same time, 'line_start' has been
967
967
                 advanced earlier, and the following loop is never really
968
968
                 executed.  */
969
969
 
983
983
          else if (input_reference)
984
984
            {
985
985
 
986
 
              /* If only input referencing, `line_start' has been computed
 
986
              /* If only input referencing, 'line_start' has been computed
987
987
                 earlier to detect the case the word matched would be part
988
988
                 of the reference.  The reference position is simply the
989
 
                 value of `line_start'.  */
 
989
                 value of 'line_start'.  */
990
990
 
991
991
              occurs_cursor->reference
992
992
                = (DELTA) (line_start - possible_key.start);
1051
1051
          /* First check if this is a diacriticized character.
1052
1052
 
1053
1053
             This works only for TeX.  I do not know how diacriticized
1054
 
             letters work with `roff'.  Please someone explain it to me!  */
 
1054
             letters work with 'roff'.  Please someone explain it to me!  */
1055
1055
 
1056
1056
          diacritic = todiac (character);
1057
1057
          if (diacritic != 0 && output_format == TEX_FORMAT)
1089
1089
                  break;
1090
1090
 
1091
1091
                case 3:         /* Grave accent */
1092
 
                  printf ("\\`%s%c", (base == 'i' ? "\\" : ""), base);
 
1092
                  printf ("\\'%s%c", (base == 'i' ? "\\" : ""), base);
1093
1093
                  break;
1094
1094
 
1095
1095
                case 4:         /* Circumflex accent */
1144
1144
          else
1145
1145
 
1146
1146
            /* This is not a diacritic character, so handle cases which are
1147
 
               really specific to `roff' or TeX.  All white space processing
 
1147
               really specific to 'roff' or TeX.  All white space processing
1148
1148
               is done as the default case of this switch.  */
1149
1149
 
1150
1150
            switch (character)
1321
1321
 
1322
1322
    case ROFF_FORMAT:
1323
1323
 
1324
 
      /* `Quote' characters should be doubled.  */
 
1324
      /* 'Quote' characters should be doubled.  */
1325
1325
 
1326
1326
      edited_flag['"'] = 1;
1327
1327
      break;
1355
1355
  char *cursor;                 /* running cursor in source text */
1356
1356
  char *left_context_start;     /* start of left context */
1357
1357
  char *right_context_end;      /* end of right context */
1358
 
  char *left_field_start;       /* conservative start for `head'/`before' */
 
1358
  char *left_field_start;       /* conservative start for 'head'/'before' */
1359
1359
  int file_index;               /* index in text input file arrays */
1360
1360
  const char *file_name;        /* file name for reference */
1361
1361
  int line_ordinal;             /* line ordinal for reference */
1362
1362
 
1363
 
  /* Define `keyafter', start of left context and end of right context.
1364
 
     `keyafter' starts at the saved position for keyword and extend to the
 
1363
  /* Define 'keyafter', start of left context and end of right context.
 
1364
     'keyafter' starts at the saved position for keyword and extend to the
1365
1365
     right from the end of the keyword, eating separators or full words, but
1366
 
     not beyond maximum allowed width for `keyafter' field or limit for the
 
1366
     not beyond maximum allowed width for 'keyafter' field or limit for the
1367
1367
     right context.  Suffix spaces will be removed afterwards.  */
1368
1368
 
1369
1369
  keyafter.start = occurs->key.start;
1386
1386
  SKIP_WHITE_BACKWARDS (keyafter.end, keyafter.start);
1387
1387
 
1388
1388
  /* When the left context is wide, it might take some time to catch up from
1389
 
     the left context boundary to the beginning of the `head' or `before'
 
1389
     the left context boundary to the beginning of the 'head' or 'before'
1390
1390
     fields.  So, in this case, to speed the catchup, we jump back from the
1391
1391
     keyword, using some secure distance, possibly falling in the middle of
1392
1392
     a word.  A secure backward jump would be at least half the maximum
1394
1394
     input.  We conclude this backward jump by a skip forward of at least
1395
1395
     one word.  In this manner, we should not inadvertently accept only part
1396
1396
     of a word.  From the reached point, when it will be time to fix the
1397
 
     beginning of `head' or `before' fields, we will skip forward words or
 
1397
     beginning of 'head' or 'before' fields, we will skip forward words or
1398
1398
     delimiters until we get sufficiently near.  */
1399
1399
 
1400
1400
  if (-occurs->left > half_line_width + maximum_word_length)
1406
1406
  else
1407
1407
    left_field_start = keyafter.start + occurs->left;
1408
1408
 
1409
 
  /* `before' certainly ends at the keyword, but not including separating
 
1409
  /* 'before' certainly ends at the keyword, but not including separating
1410
1410
     spaces.  It starts after than the saved value for the left context, by
1411
1411
     advancing it until it falls inside the maximum allowed width for the
1412
 
     before field.  There will be no prefix spaces either.  `before' only
 
1412
     before field.  There will be no prefix spaces either.  'before' only
1413
1413
     advances by skipping single separators or whole words. */
1414
1414
 
1415
1415
  before.start = left_field_start;
1477
1477
      tail_truncation = 0;
1478
1478
    }
1479
1479
 
1480
 
  /* `head' could not take more columns than what has been left in the right
 
1480
  /* 'head' could not take more columns than what has been left in the right
1481
1481
     context field, and a gap is mandatory.  It ends before the left
1482
1482
     context, and does not contain suffixed spaces.  Its pointer is advanced
1483
1483
     until the head field has shrunk to its allowed width.  It cannot
1554
1554
/* Formatting and actual output - control routines.  */
1555
1555
 
1556
1556
/*----------------------------------------------------------------------.
1557
 
| Output the current output fields as one line for `troff' or `nroff'.  |
 
1557
| Output the current output fields as one line for 'troff' or 'nroff'.  |
1558
1558
`----------------------------------------------------------------------*/
1559
1559
 
1560
1560
static void
1561
1561
output_one_roff_line (void)
1562
1562
{
1563
 
  /* Output the `tail' field.  */
 
1563
  /* Output the 'tail' field.  */
1564
1564
 
1565
1565
  printf (".%s \"", macro_name);
1566
1566
  print_field (tail);
1568
1568
    fputs (truncation_string, stdout);
1569
1569
  putchar ('"');
1570
1570
 
1571
 
  /* Output the `before' field.  */
 
1571
  /* Output the 'before' field.  */
1572
1572
 
1573
1573
  fputs (" \"", stdout);
1574
1574
  if (before_truncation)
1576
1576
  print_field (before);
1577
1577
  putchar ('"');
1578
1578
 
1579
 
  /* Output the `keyafter' field.  */
 
1579
  /* Output the 'keyafter' field.  */
1580
1580
 
1581
1581
  fputs (" \"", stdout);
1582
1582
  print_field (keyafter);
1584
1584
    fputs (truncation_string, stdout);
1585
1585
  putchar ('"');
1586
1586
 
1587
 
  /* Output the `head' field.  */
 
1587
  /* Output the 'head' field.  */
1588
1588
 
1589
1589
  fputs (" \"", stdout);
1590
1590
  if (head_truncation)
1592
1592
  print_field (head);
1593
1593
  putchar ('"');
1594
1594
 
1595
 
  /* Conditionally output the `reference' field.  */
 
1595
  /* Conditionally output the 'reference' field.  */
1596
1596
 
1597
1597
  if (auto_reference || input_reference)
1598
1598
    {
1605
1605
}
1606
1606
 
1607
1607
/*---------------------------------------------------------.
1608
 
| Output the current output fields as one line for `TeX'.  |
 
1608
| Output the current output fields as one line for 'TeX'.  |
1609
1609
`---------------------------------------------------------*/
1610
1610
 
1611
1611
static void
1654
1654
      if (auto_reference)
1655
1655
        {
1656
1656
 
1657
 
          /* Output the `reference' field, in such a way that GNU emacs
 
1657
          /* Output the 'reference' field, in such a way that GNU emacs
1658
1658
             next-error will handle it.  The ending colon is taken from the
1659
1659
             gap which follows.  */
1660
1660
 
1668
1668
      else
1669
1669
        {
1670
1670
 
1671
 
          /* Output the `reference' field and its following gap.  */
 
1671
          /* Output the 'reference' field and its following gap.  */
1672
1672
 
1673
1673
          print_field (reference);
1674
1674
          print_spaces (reference_max_width
1679
1679
 
1680
1680
  if (tail.start < tail.end)
1681
1681
    {
1682
 
      /* Output the `tail' field.  */
 
1682
      /* Output the 'tail' field.  */
1683
1683
 
1684
1684
      print_field (tail);
1685
1685
      if (tail_truncation)
1696
1696
                  - (before.end - before.start)
1697
1697
                  - (before_truncation ? truncation_string_length : 0));
1698
1698
 
1699
 
  /* Output the `before' field.  */
 
1699
  /* Output the 'before' field.  */
1700
1700
 
1701
1701
  if (before_truncation)
1702
1702
    fputs (truncation_string, stdout);
1704
1704
 
1705
1705
  print_spaces (gap_size);
1706
1706
 
1707
 
  /* Output the `keyafter' field.  */
 
1707
  /* Output the 'keyafter' field.  */
1708
1708
 
1709
1709
  print_field (keyafter);
1710
1710
  if (keyafter_truncation)
1712
1712
 
1713
1713
  if (head.start < head.end)
1714
1714
    {
1715
 
      /* Output the `head' field.  */
 
1715
      /* Output the 'head' field.  */
1716
1716
 
1717
1717
      print_spaces (half_line_width
1718
1718
                    - (keyafter.end - keyafter.start)
1732
1732
 
1733
1733
  if ((auto_reference || input_reference) && right_reference)
1734
1734
    {
1735
 
      /* Output the `reference' field.  */
 
1735
      /* Output the 'reference' field.  */
1736
1736
 
1737
1737
      print_spaces (gap_size);
1738
1738
      print_field (reference);
1811
1811
usage (int status)
1812
1812
{
1813
1813
  if (status != EXIT_SUCCESS)
1814
 
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
1815
 
             program_name);
 
1814
    emit_try_help ();
1816
1815
  else
1817
1816
    {
1818
1817
      printf (_("\
1828
1827
"), stdout);
1829
1828
      fputs (_("\
1830
1829
  -A, --auto-reference           output automatically generated references\n\
1831
 
  -G, --traditional              behave more like System V `ptx'\n\
 
1830
  -G, --traditional              behave more like System V 'ptx'\n\
1832
1831
  -F, --flag-truncation=STRING   use STRING for flagging line truncations\n\
1833
1832
"), stdout);
1834
1833
      fputs (_("\
1835
 
  -M, --macro-name=STRING        macro name to use instead of `xx'\n\
 
1834
  -M, --macro-name=STRING        macro name to use instead of 'xx'\n\
1836
1835
  -O, --format=roff              generate output as roff directives\n\
1837
1836
  -R, --right-side-refs          put references at right, not counted in -w\n\
1838
1837
  -S, --sentence-regexp=REGEXP   for end of lines or end of sentences\n\
1855
1854
      fputs (VERSION_OPTION_DESCRIPTION, stdout);
1856
1855
      fputs (_("\
1857
1856
\n\
1858
 
With no FILE or if FILE is -, read Standard Input.  `-F /' by default.\n\
 
1857
With no FILE or if FILE is -, read Standard Input.  '-F /' by default.\n\
1859
1858
"), stdout);
1860
1859
      emit_ancillary_info ();
1861
1860
    }
2085
2084
    }
2086
2085
 
2087
2086
  /* If the output format has not been explicitly selected, choose dumb
2088
 
     terminal format if GNU extensions are enabled, else `roff' format.  */
 
2087
     terminal format if GNU extensions are enabled, else 'roff' format.  */
2089
2088
 
2090
2089
  if (output_format == UNKNOWN_FORMAT)
2091
2090
    output_format = gnu_extensions ? DUMB_FORMAT : ROFF_FORMAT;
2094
2093
 
2095
2094
  initialize_regex ();
2096
2095
 
2097
 
  /* Read `Break character' file, if any.  */
 
2096
  /* Read 'Break character' file, if any.  */
2098
2097
 
2099
2098
  if (break_file)
2100
2099
    digest_break_file (break_file);
2101
2100
 
2102
 
  /* Read `Ignore words' file and `Only words' files, if any.  If any of
 
2101
  /* Read 'Ignore words' file and 'Only words' files, if any.  If any of
2103
2102
     these files is empty, reset the name of the file to NULL, to avoid
2104
2103
     unnecessary calls to search_table. */
2105
2104