bug-gettext
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gettext] [PATCH] Extend --add-location option to suppress line numb


From: Daiki Ueno
Subject: [bug-gettext] [PATCH] Extend --add-location option to suppress line number output
Date: Tue, 25 Mar 2014 16:06:10 +0900

The --add-location option of msgattrib, msgcat, msgcomm, msgconv,
msgen, msgfilter, msggrep, msgmerge, msguniq, and xgettext
commands now takes an optional argument 'never', 'full', or
'file', to control the format of "#: ..."  comments.

The default catalog reader changed to always remember file
positions and thus line numbers can be suppressed in output phase
rather than input phase.
---
 gettext-tools/doc/ChangeLog      |   6 ++
 gettext-tools/doc/msgattrib.texi |   8 +-
 gettext-tools/doc/msgcat.texi    |   8 +-
 gettext-tools/doc/msgcomm.texi   |   8 +-
 gettext-tools/doc/msgconv.texi   |   9 +-
 gettext-tools/doc/msgen.texi     |   9 +-
 gettext-tools/doc/msgfilter.texi |   9 +-
 gettext-tools/doc/msggrep.texi   |   9 +-
 gettext-tools/doc/msgmerge.texi  |   9 +-
 gettext-tools/doc/msguniq.texi   |   8 +-
 gettext-tools/doc/xgettext.texi  |   8 +-
 gettext-tools/src/ChangeLog      |  42 +++++++++
 gettext-tools/src/msgattrib.c    |  15 ++--
 gettext-tools/src/msgcat.c       |  15 ++--
 gettext-tools/src/msgcomm.c      |  15 ++--
 gettext-tools/src/msgconv.c      |  21 +++--
 gettext-tools/src/msgen.c        |  24 +++--
 gettext-tools/src/msgfilter.c    |  21 +++--
 gettext-tools/src/msgfmt.c       |   4 +-
 gettext-tools/src/msggrep.c      |  21 +++--
 gettext-tools/src/msgmerge.c     |  21 +++--
 gettext-tools/src/msguniq.c      |  15 ++--
 gettext-tools/src/read-catalog.c |  69 ++++++--------
 gettext-tools/src/read-catalog.h |   8 --
 gettext-tools/src/write-po.c     |  86 ++++++++++++++++--
 gettext-tools/src/write-po.h     |  13 +++
 gettext-tools/src/x-po.c         |   1 -
 gettext-tools/src/xgettext.c     |  18 ++--
 gettext-tools/tests/ChangeLog    |  15 ++++
 gettext-tools/tests/Makefile.am  |  20 ++---
 gettext-tools/tests/msgattrib-18 |  98 ++++++++++++++++++++
 gettext-tools/tests/msgcat-19    |  66 ++++++++++++++
 gettext-tools/tests/msgcomm-28   |  37 ++++++++
 gettext-tools/tests/msgconv-7    |  43 +++++++++
 gettext-tools/tests/msgen-4      |  68 ++++++++++++++
 gettext-tools/tests/msgfilter-5  | 169 ++++++++++++++++++++++++++++++++++
 gettext-tools/tests/msggrep-11   | 189 +++++++++++++++++++++++++++++++++++++++
 gettext-tools/tests/msgmerge-25  |  69 ++++++++++++++
 gettext-tools/tests/msguniq-7    |  31 +++++++
 gettext-tools/tests/xgettext-10  |  36 ++++++++
 40 files changed, 1180 insertions(+), 161 deletions(-)
 create mode 100755 gettext-tools/tests/msgattrib-18
 create mode 100755 gettext-tools/tests/msgcat-19
 create mode 100755 gettext-tools/tests/msgcomm-28
 create mode 100755 gettext-tools/tests/msgconv-7
 create mode 100755 gettext-tools/tests/msgen-4
 create mode 100755 gettext-tools/tests/msgfilter-5
 create mode 100755 gettext-tools/tests/msggrep-11
 create mode 100755 gettext-tools/tests/msgmerge-25
 create mode 100755 gettext-tools/tests/msguniq-7
 create mode 100755 gettext-tools/tests/xgettext-10

diff --git a/gettext-tools/doc/ChangeLog b/gettext-tools/doc/ChangeLog
index beadd9c..3621a4e 100644
--- a/gettext-tools/doc/ChangeLog
+++ b/gettext-tools/doc/ChangeLog
@@ -1,3 +1,9 @@
+2014-03-25  Daiki Ueno  <address@hidden>
+
+       * msgattrib.texi: Document the optional argument of
+       --add-location.
+       * msgcat.texi: Likewise.
+
 2014-03-15  Daiki Ueno  <address@hidden>
 
        * FAQ.html: Point to address@hidden rather than
diff --git a/gettext-tools/doc/msgattrib.texi b/gettext-tools/doc/msgattrib.texi
index 0f2749b..998b8b0 100644
--- a/gettext-tools/doc/msgattrib.texi
+++ b/gettext-tools/doc/msgattrib.texi
@@ -214,11 +214,17 @@ Write the .po file using indented style.
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
 @item -n
address@hidden --add-location
address@hidden address@hidden
 @opindex address@hidden, @code{msgattrib} option}
 @opindex address@hidden, @code{msgattrib} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgattrib} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msgcat.texi b/gettext-tools/doc/msgcat.texi
index 5b6b095..7c15050 100644
--- a/gettext-tools/doc/msgcat.texi
+++ b/gettext-tools/doc/msgcat.texi
@@ -147,11 +147,17 @@ Write the .po file using indented style.
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
 @item -n
address@hidden --add-location
address@hidden address@hidden
 @opindex address@hidden, @code{msgcat} option}
 @opindex address@hidden, @code{msgcat} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgcat} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msgcomm.texi b/gettext-tools/doc/msgcomm.texi
index 29ef820..ae7c927 100644
--- a/gettext-tools/doc/msgcomm.texi
+++ b/gettext-tools/doc/msgcomm.texi
@@ -128,11 +128,17 @@ Write the .po file using indented style.
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
 @item -n
address@hidden --add-location
address@hidden address@hidden
 @opindex address@hidden, @code{msgcomm} option}
 @opindex address@hidden, @code{msgcomm} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgcomm} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msgconv.texi b/gettext-tools/doc/msgconv.texi
index 6e58fd2..805a76f 100644
--- a/gettext-tools/doc/msgconv.texi
+++ b/gettext-tools/doc/msgconv.texi
@@ -100,10 +100,17 @@ Write the .po file using indented style.
 @opindex address@hidden, @code{msgconv} option}
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
address@hidden --add-location
address@hidden -n
address@hidden address@hidden
 @opindex address@hidden, @code{msgconv} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgconv} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msgen.texi b/gettext-tools/doc/msgen.texi
index 82f210d..3f61fa4 100644
--- a/gettext-tools/doc/msgen.texi
+++ b/gettext-tools/doc/msgen.texi
@@ -100,10 +100,17 @@ Write the .po file using indented style.
 @opindex address@hidden, @code{msgen} option}
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
address@hidden --add-location
address@hidden -n
address@hidden address@hidden
 @opindex address@hidden, @code{msgen} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgen} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msgfilter.texi b/gettext-tools/doc/msgfilter.texi
index 05c3fb8..73ea7c8 100644
--- a/gettext-tools/doc/msgfilter.texi
+++ b/gettext-tools/doc/msgfilter.texi
@@ -172,10 +172,17 @@ filtering like any other message.
 @opindex address@hidden, @code{msgfilter} option}
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
address@hidden --add-location
address@hidden -n
address@hidden address@hidden
 @opindex address@hidden, @code{msgfilter} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgfilter} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msggrep.texi b/gettext-tools/doc/msggrep.texi
index 31bc815..229b924 100644
--- a/gettext-tools/doc/msggrep.texi
+++ b/gettext-tools/doc/msggrep.texi
@@ -200,10 +200,17 @@ Write the .po file using indented style.
 @opindex address@hidden, @code{msggrep} option}
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
address@hidden --add-location
address@hidden -n
address@hidden address@hidden
 @opindex address@hidden, @code{msggrep} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msggrep} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msgmerge.texi b/gettext-tools/doc/msgmerge.texi
index 3ecf024..ad76f0e 100644
--- a/gettext-tools/doc/msgmerge.texi
+++ b/gettext-tools/doc/msgmerge.texi
@@ -188,10 +188,17 @@ Write the .po file using indented style.
 @opindex address@hidden, @code{msgmerge} option}
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
address@hidden --add-location
address@hidden -n
address@hidden address@hidden
 @opindex address@hidden, @code{msgmerge} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msgmerge} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/msguniq.texi b/gettext-tools/doc/msguniq.texi
index 120a8fe..4bb6ffd 100644
--- a/gettext-tools/doc/msguniq.texi
+++ b/gettext-tools/doc/msguniq.texi
@@ -125,11 +125,17 @@ Write the .po file using indented style.
 Do not write @samp{#: @var{filename}:@var{line}} lines.
 
 @item -n
address@hidden --add-location
address@hidden address@hidden
 @opindex address@hidden, @code{msguniq} option}
 @opindex address@hidden, @code{msguniq} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{msguniq} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/doc/xgettext.texi b/gettext-tools/doc/xgettext.texi
index 1089e9c..c8adc27 100644
--- a/gettext-tools/doc/xgettext.texi
+++ b/gettext-tools/doc/xgettext.texi
@@ -395,11 +395,17 @@ this option makes it harder for technically skilled 
translators to understand
 each message's context.
 
 @item -n
address@hidden --add-location
address@hidden address@hidden
 @opindex address@hidden, @code{xgettext} option}
 @opindex address@hidden, @code{xgettext} option}
 Generate @samp{#: @var{filename}:@var{line}} lines (default).
 
+The optional @var{type} can be either @samp{full}, @samp{file}, or
address@hidden  If it is not given or @samp{full}, it generates the
+lines with both file name and line number.  If it is @samp{file}, the
+line number part is omitted.  If it is @samp{never}, it completely
+suppresses the lines (same as @code{--no-location}).
+
 @item --strict
 @opindex address@hidden, @code{xgettext} option}
 Write out a strict Uniforum conforming PO file.  Note that this
diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog
index 06a59bd..670ce29 100644
--- a/gettext-tools/src/ChangeLog
+++ b/gettext-tools/src/ChangeLog
@@ -1,3 +1,45 @@
+2014-03-25  Daiki Ueno  <address@hidden>
+
+       Extend --add-location option to suppress line number output
+       The --add-location option of msgattrib, msgcat, msgcomm, msgconv,
+       msgen, msgfilter, msggrep, msgmerge, msguniq, and xgettext
+       commands now got new semantics.  It takes an optional argument
+       'never', 'full', or 'file', to control the format of "#: ..."
+       comments.
+       The default catalog reader changed to always remember file
+       positions and thus line numbers can be suppressed in output phase
+       rather than input phase.
+       Feature requested in:
+       <https://lists.gnu.org/archive/html/bug-gettext/2013-08/msg00039.html>.
+       * read-catalog.h (line_comment): Abolish.
+       (DEFAULT_CATALOG_READER_TY): Remove handle_filepos_comments field.
+       * read-catalog.c (line_comment): Abolish.
+       (default_destructor, default_copy_comment_state)
+       (default_reset_comment_state, default_comment_filepos): Always
+       remember filepos.
+       (default_parse_brief, read_catalog_stream): Adjust to the change.
+       * write-po.h (enum filepos_comment_type): New enum.
+       (message_print_style_filepos): New function declaration.
+       (handle_filepos_comment_option): New function declaration.
+       * write-po.c (message_print_style_filepos): New function
+       (handle_filepos_comment_option): New function.
+       (message_print_comment_filepos): Uniquify mp->filepos elements
+       ignoring line number if filepos_comment_type is
+       filepos_comment_file.
+       * msgfmt.c: Adjust to the change.
+       * msgattrib.c (long_options, main): Allow --add-location option to
+       take an optional format specifier.
+       * msgcat.c (long_options, main): Likewise.
+       * msgcomm.c (long_options, main): Likewise.
+       * msguniq.c (long_options, main): Likewise.
+       * xgettext.c (long_options, main): Likewise.
+       * msgconv.c (long_options, main): Likewise; add a new option -n as
+       an alias of --add-location.
+       * msgen.c (long_options, main): Likewise.
+       * msgfilter.c (long_options, main): Likewise.
+       * msggrep.c (long_options, main): Likewise.
+       * msgmerge.c (long_options, main): Likewise.
+
 2014-03-12  Daiki Ueno  <address@hidden>
 
        xgettext: Fix infloop on loading Glade files with non-DL expat
diff --git a/gettext-tools/src/msgattrib.c b/gettext-tools/src/msgattrib.c
index 7732315..01b6f97 100644
--- a/gettext-tools/src/msgattrib.c
+++ b/gettext-tools/src/msgattrib.c
@@ -80,7 +80,7 @@ static int to_change;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "clear-fuzzy", no_argument, NULL, CHAR_MAX + 8 },
   { "clear-obsolete", no_argument, NULL, CHAR_MAX + 10 },
   { "clear-previous", no_argument, NULL, CHAR_MAX + 18 },
@@ -94,7 +94,7 @@ static const struct option long_options[] =
   { "indent", no_argument, NULL, 'i' },
   { "no-escape", no_argument, NULL, 'e' },
   { "no-fuzzy", no_argument, NULL, CHAR_MAX + 3 },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 22 },
   { "no-obsolete", no_argument, NULL, CHAR_MAX + 5 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 13 },
   { "obsolete", no_argument, NULL, CHAR_MAX + 12 },
@@ -207,7 +207,8 @@ main (int argc, char **argv)
         break;
 
       case 'n':
-        line_comment = 1;
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
         break;
 
       case 'o':
@@ -331,6 +332,10 @@ main (int argc, char **argv)
         to_change |= ADD_PREV;
         break;
 
+      case CHAR_MAX + 22: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         /* NOTREACHED */
@@ -367,10 +372,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     }
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
diff --git a/gettext-tools/src/msgcat.c b/gettext-tools/src/msgcat.c
index 7c36730..0cc432c 100644
--- a/gettext-tools/src/msgcat.c
+++ b/gettext-tools/src/msgcat.c
@@ -62,7 +62,7 @@ static const char *to_code;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 5 },
   { "directory", required_argument, NULL, 'D' },
   { "escape", no_argument, NULL, 'E' },
@@ -72,7 +72,7 @@ static const struct option long_options[] =
   { "indent", no_argument, NULL, 'i' },
   { "lang", required_argument, NULL, CHAR_MAX + 7 },
   { "no-escape", no_argument, NULL, 'e' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 8 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "output-file", required_argument, NULL, 'o' },
   { "properties-input", no_argument, NULL, 'P' },
@@ -202,7 +202,8 @@ main (int argc, char **argv)
         break;
 
       case 'n':
-        line_comment = 1;
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
         break;
 
       case 'o':
@@ -276,6 +277,10 @@ main (int argc, char **argv)
         catalogname = optarg;
         break;
 
+      case CHAR_MAX + 8: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         /* NOTREACHED */
@@ -307,10 +312,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     }
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
diff --git a/gettext-tools/src/msgcomm.c b/gettext-tools/src/msgcomm.c
index e965dba..daddf2b 100644
--- a/gettext-tools/src/msgcomm.c
+++ b/gettext-tools/src/msgcomm.c
@@ -63,7 +63,7 @@ static const char *to_code;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 5 },
   { "directory", required_argument, NULL, 'D' },
   { "escape", no_argument, NULL, 'E' },
@@ -72,7 +72,7 @@ static const struct option long_options[] =
   { "help", no_argument, NULL, 'h' },
   { "indent", no_argument, NULL, 'i' },
   { "no-escape", no_argument, NULL, 'e' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 7 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "omit-header", no_argument, NULL, CHAR_MAX + 1 },
   { "output", required_argument, NULL, 'o' }, /* for backward compatibility */
@@ -197,7 +197,8 @@ main (int argc, char *argv[])
         break;
 
       case 'n':
-        line_comment = 1;
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
         break;
 
       case 'o':
@@ -267,6 +268,10 @@ main (int argc, char *argv[])
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 7: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         /* NOTREACHED */
@@ -292,10 +297,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     usage (EXIT_SUCCESS);
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
diff --git a/gettext-tools/src/msgconv.c b/gettext-tools/src/msgconv.c
index af1361a..5c9f7ea 100644
--- a/gettext-tools/src/msgconv.c
+++ b/gettext-tools/src/msgconv.c
@@ -60,7 +60,7 @@ static const char *to_code;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 4 },
   { "directory", required_argument, NULL, 'D' },
   { "escape", no_argument, NULL, 'E' },
@@ -68,7 +68,7 @@ static const struct option long_options[] =
   { "help", no_argument, NULL, 'h' },
   { "indent", no_argument, NULL, 'i' },
   { "no-escape", no_argument, NULL, 'e' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 6 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 1 },
   { "output-file", required_argument, NULL, 'o' },
   { "properties-input", no_argument, NULL, 'P' },
@@ -131,7 +131,7 @@ main (int argc, char **argv)
   output_file = NULL;
   input_file = NULL;
 
-  while ((opt = getopt_long (argc, argv, "D:eEFhio:pPst:Vw:", long_options,
+  while ((opt = getopt_long (argc, argv, "D:eEFhin:o:pPst:Vw:", long_options,
                              NULL))
          != EOF)
     switch (opt)
@@ -163,6 +163,11 @@ main (int argc, char **argv)
         message_print_style_indent ();
         break;
 
+      case 'n':
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
+        break;
+
       case 'o':
         output_file = optarg;
         break;
@@ -222,6 +227,10 @@ main (int argc, char **argv)
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 6: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         break;
@@ -258,10 +267,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     }
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
@@ -360,7 +365,7 @@ Output details:\n"));
       printf (_("\
       --no-location           suppress '#: filename:line' lines\n"));
       printf (_("\
-      --add-location          preserve '#: filename:line' lines (default)\n"));
+  -n, --add-location          preserve '#: filename:line' lines (default)\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
diff --git a/gettext-tools/src/msgen.c b/gettext-tools/src/msgen.c
index 2ec3d5e..e33c61a 100644
--- a/gettext-tools/src/msgen.c
+++ b/gettext-tools/src/msgen.c
@@ -57,7 +57,7 @@ static int force_po;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 5 },
   { "directory", required_argument, NULL, 'D' },
   { "escape", no_argument, NULL, 'E' },
@@ -66,7 +66,7 @@ static const struct option long_options[] =
   { "indent", no_argument, NULL, 'i' },
   { "lang", required_argument, NULL, CHAR_MAX + 4 },
   { "no-escape", no_argument, NULL, 'e' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 7 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 1 },
   { "output-file", required_argument, NULL, 'o' },
   { "properties-input", no_argument, NULL, 'P' },
@@ -128,8 +128,9 @@ main (int argc, char **argv)
   do_version = false;
   output_file = NULL;
 
-  while ((opt = getopt_long (argc, argv, "D:eEFhio:pPsVw:", long_options, 
NULL))
-         != EOF)
+  while ((opt = getopt_long (argc, argv,
+                             "D:eEFhin:o:pPsVw:",
+                             long_options, NULL)) != EOF)
     switch (opt)
       {
       case '\0':                /* Long option.  */
@@ -159,6 +160,11 @@ main (int argc, char **argv)
         message_print_style_indent ();
         break;
 
+      case 'n':
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
+        break;
+
       case 'o':
         output_file = optarg;
         break;
@@ -218,6 +224,10 @@ main (int argc, char **argv)
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 7: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         break;
@@ -255,10 +265,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     }
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
@@ -355,7 +361,7 @@ Output details:\n"));
       printf (_("\
       --no-location           suppress '#: filename:line' lines\n"));
       printf (_("\
-      --add-location          preserve '#: filename:line' lines (default)\n"));
+  -n, --add-location          preserve '#: filename:line' lines (default)\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
diff --git a/gettext-tools/src/msgfilter.c b/gettext-tools/src/msgfilter.c
index c414140..b92eef0 100644
--- a/gettext-tools/src/msgfilter.c
+++ b/gettext-tools/src/msgfilter.c
@@ -87,7 +87,7 @@ static void (*filter) (const char *str, size_t len, char 
**resultp, size_t *leng
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 6 },
   { "directory", required_argument, NULL, 'D' },
   { "escape", no_argument, NULL, 'E' },
@@ -97,7 +97,7 @@ static const struct option long_options[] =
   { "input", required_argument, NULL, 'i' },
   { "keep-header", no_argument, &keep_header, 1 },
   { "no-escape", no_argument, NULL, CHAR_MAX + 2 },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 8 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 3 },
   { "output-file", required_argument, NULL, 'o' },
   { "properties-input", no_argument, NULL, 'P' },
@@ -164,7 +164,7 @@ main (int argc, char **argv)
 
   /* The '+' in the options string causes option parsing to terminate when
      the first non-option, i.e. the subprogram name, is encountered.  */
-  while ((opt = getopt_long (argc, argv, "+D:EFhi:o:pPsVw:", long_options,
+  while ((opt = getopt_long (argc, argv, "+D:EFhi:n:o:pPsVw:", long_options,
                              NULL))
          != EOF)
     switch (opt)
@@ -197,6 +197,11 @@ main (int argc, char **argv)
         input_file = optarg;
         break;
 
+      case 'n':
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
+        break;
+
       case 'o':
         output_file = optarg;
         break;
@@ -260,6 +265,10 @@ main (int argc, char **argv)
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 8: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         break;
@@ -290,10 +299,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
   sub_name = argv[optind];
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
@@ -456,7 +461,7 @@ Output details:\n"));
       printf (_("\
       --no-location           suppress '#: filename:line' lines\n"));
       printf (_("\
-      --add-location          preserve '#: filename:line' lines (default)\n"));
+  -n, --add-location          preserve '#: filename:line' lines (default)\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
diff --git a/gettext-tools/src/msgfmt.c b/gettext-tools/src/msgfmt.c
index 4da999a..e51319d 100644
--- a/gettext-tools/src/msgfmt.c
+++ b/gettext-tools/src/msgfmt.c
@@ -846,8 +846,7 @@ is_nonobsolete (const message_ty *mp)
    default_catalog_reader_ty.  Its particularities are:
    - The header entry check is performed on-the-fly.
    - Comments are not stored, they are discarded right away.
-     (This is achieved by setting handle_comments = false and
-     handle_filepos_comments = false.)
+     (This is achieved by setting handle_comments = false.)
    - The multi-domain handling is adapted to our domain_list.
  */
 
@@ -1107,7 +1106,6 @@ read_catalog_file_msgfmt (char *filename, 
catalog_input_format_ty input_syntax)
 
   pop = default_catalog_reader_alloc (&msgfmt_methods);
   pop->handle_comments = false;
-  pop->handle_filepos_comments = false;
   pop->allow_domain_directives = true;
   pop->allow_duplicates = false;
   pop->allow_duplicates_if_same_msgstr = false;
diff --git a/gettext-tools/src/msggrep.c b/gettext-tools/src/msggrep.c
index 3b12e93..73ccb94 100644
--- a/gettext-tools/src/msggrep.c
+++ b/gettext-tools/src/msggrep.c
@@ -91,7 +91,7 @@ static struct grep_task grep_task[5];
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 9 },
   { "comment", no_argument, NULL, 'C' },
   { "directory", required_argument, NULL, 'D' },
@@ -111,7 +111,7 @@ static const struct option long_options[] =
   { "msgid", no_argument, NULL, 'K' },
   { "msgstr", no_argument, NULL, 'T' },
   { "no-escape", no_argument, NULL, CHAR_MAX + 3 },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 11 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 6 },
   { "output-file", required_argument, NULL, 'o' },
   { "properties-input", no_argument, NULL, 'P' },
@@ -196,7 +196,7 @@ main (int argc, char **argv)
       gt->case_insensitive = false;
     }
 
-  while ((opt = getopt_long (argc, argv, "CD:e:Ef:FhiJKM:N:o:pPTvVw:X",
+  while ((opt = getopt_long (argc, argv, "CD:e:Ef:FhiJKM:n:N:o:pPTvVw:X",
                              long_options, NULL))
          != EOF)
     switch (opt)
@@ -310,6 +310,11 @@ error while reading \"%s\""), optarg);
         string_list_append (domain_names, optarg);
         break;
 
+      case 'n':
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
+        break;
+
       case 'N':
         string_list_append (location_files, optarg);
         break;
@@ -397,6 +402,10 @@ error while reading \"%s\""), optarg);
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 11: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         break;
@@ -433,10 +442,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     }
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
@@ -603,7 +608,7 @@ Output details:\n"));
       printf (_("\
       --no-location           suppress '#: filename:line' lines\n"));
       printf (_("\
-      --add-location          preserve '#: filename:line' lines (default)\n"));
+  -n, --add-location          preserve '#: filename:line' lines (default)\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
diff --git a/gettext-tools/src/msgmerge.c b/gettext-tools/src/msgmerge.c
index 3f96d3e..7c7add9 100644
--- a/gettext-tools/src/msgmerge.c
+++ b/gettext-tools/src/msgmerge.c
@@ -107,7 +107,7 @@ static const char *backup_suffix_string;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "backup", required_argument, NULL, CHAR_MAX + 1 },
   { "color", optional_argument, NULL, CHAR_MAX + 9 },
   { "compendium", required_argument, NULL, 'C', },
@@ -120,7 +120,7 @@ static const struct option long_options[] =
   { "multi-domain", no_argument, NULL, 'm' },
   { "no-escape", no_argument, NULL, 'e' },
   { "no-fuzzy-matching", no_argument, NULL, 'N' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 11 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 4 },
   { "output-file", required_argument, NULL, 'o' },
   { "previous", no_argument, NULL, CHAR_MAX + 7 },
@@ -204,7 +204,7 @@ main (int argc, char **argv)
   do_version = false;
   output_file = NULL;
 
-  while ((opt = getopt_long (argc, argv, "C:D:eEFhimNo:pPqsUvVw:",
+  while ((opt = getopt_long (argc, argv, "C:D:eEFhimn:No:pPqsUvVw:",
                              long_options, NULL))
          != EOF)
     switch (opt)
@@ -244,6 +244,11 @@ main (int argc, char **argv)
         multi_domain_mode = true;
         break;
 
+      case 'n':
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
+        break;
+
       case 'N':
         use_fuzzy_matching = false;
         break;
@@ -331,6 +336,10 @@ main (int argc, char **argv)
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 11: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         break;
@@ -392,10 +401,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
         }
     }
 
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
@@ -581,7 +586,7 @@ Output details:\n"));
       printf (_("\
       --no-location           suppress '#: filename:line' lines\n"));
       printf (_("\
-      --add-location          preserve '#: filename:line' lines (default)\n"));
+  -n, --add-location          preserve '#: filename:line' lines (default)\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
diff --git a/gettext-tools/src/msguniq.c b/gettext-tools/src/msguniq.c
index 9f1add6..24f4c31 100644
--- a/gettext-tools/src/msguniq.c
+++ b/gettext-tools/src/msguniq.c
@@ -60,7 +60,7 @@ static const char *to_code;
 /* Long options.  */
 static const struct option long_options[] =
 {
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "color", optional_argument, NULL, CHAR_MAX + 5 },
   { "directory", required_argument, NULL, 'D' },
   { "escape", no_argument, NULL, 'E' },
@@ -68,7 +68,7 @@ static const struct option long_options[] =
   { "help", no_argument, NULL, 'h' },
   { "indent", no_argument, NULL, 'i' },
   { "no-escape", no_argument, NULL, 'e' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 7 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "output-file", required_argument, NULL, 'o' },
   { "properties-input", no_argument, NULL, 'P' },
@@ -175,7 +175,8 @@ main (int argc, char **argv)
         break;
 
       case 'n':
-        line_comment = 1;
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
         break;
 
       case 'o':
@@ -246,6 +247,10 @@ main (int argc, char **argv)
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 7: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         /* NOTREACHED */
@@ -282,10 +287,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     }
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
diff --git a/gettext-tools/src/read-catalog.c b/gettext-tools/src/read-catalog.c
index 51e96e8..4642249 100644
--- a/gettext-tools/src/read-catalog.c
+++ b/gettext-tools/src/read-catalog.c
@@ -112,6 +112,7 @@ void
 default_destructor (abstract_catalog_reader_ty *that)
 {
   default_catalog_reader_ty *this = (default_catalog_reader_ty *) that;
+  size_t j;
 
   /* Do not free this->mdlp and this->mlp.  */
   if (this->handle_comments)
@@ -121,24 +122,19 @@ default_destructor (abstract_catalog_reader_ty *that)
       if (this->comment_dot != NULL)
         string_list_free (this->comment_dot);
     }
-  if (this->handle_filepos_comments)
-    {
-      size_t j;
 
-      for (j = 0; j < this->filepos_count; ++j)
-        free (this->filepos[j].file_name);
-      if (this->filepos != NULL)
-        free (this->filepos);
-    }
+  for (j = 0; j < this->filepos_count; ++j)
+    free (this->filepos[j].file_name);
+  if (this->filepos != NULL)
+    free (this->filepos);
 }
 
 
 void
 default_parse_brief (abstract_catalog_reader_ty *that)
 {
-  /* We need to parse comments, because even if this->handle_comments and
-     this->handle_filepos_comments are false, we need to know which messages
-     are fuzzy.  */
+  /* We need to parse comments, because even if this->handle_comments
+     is false, we need to know which messages are fuzzy.  */
   po_lex_pass_comments (true);
 }
 
@@ -164,15 +160,12 @@ default_copy_comment_state (default_catalog_reader_ty 
*this, message_ty *mp)
         for (j = 0; j < this->comment_dot->nitems; ++j)
           message_comment_dot_append (mp, this->comment_dot->item[j]);
     }
-  if (this->handle_filepos_comments)
+  for (j = 0; j < this->filepos_count; ++j)
     {
-      for (j = 0; j < this->filepos_count; ++j)
-        {
-          lex_pos_ty *pp;
+      lex_pos_ty *pp;
 
-          pp = &this->filepos[j];
-          message_comment_filepos (mp, pp->file_name, pp->line_number);
-        }
+      pp = &this->filepos[j];
+      message_comment_filepos (mp, pp->file_name, pp->line_number);
     }
   mp->is_fuzzy = this->is_fuzzy;
   for (i = 0; i < NFORMATS; i++)
@@ -200,15 +193,12 @@ default_reset_comment_state (default_catalog_reader_ty 
*this)
           this->comment_dot = NULL;
         }
     }
-  if (this->handle_filepos_comments)
-    {
-      for (j = 0; j < this->filepos_count; ++j)
-        free (this->filepos[j].file_name);
-      if (this->filepos != NULL)
-        free (this->filepos);
-      this->filepos_count = 0;
-      this->filepos = NULL;
-    }
+  for (j = 0; j < this->filepos_count; ++j)
+    free (this->filepos[j].file_name);
+  if (this->filepos != NULL)
+    free (this->filepos);
+  this->filepos_count = 0;
+  this->filepos = NULL;
   this->is_fuzzy = false;
   for (i = 0; i < NFORMATS; i++)
     this->is_format[i] = undecided;
@@ -291,18 +281,14 @@ default_comment_filepos (abstract_catalog_reader_ty *that,
                          const char *name, size_t line)
 {
   default_catalog_reader_ty *this = (default_catalog_reader_ty *) that;
-
-  if (this->handle_filepos_comments)
-    {
-      size_t nbytes;
-      lex_pos_ty *pp;
-
-      nbytes = (this->filepos_count + 1) * sizeof (this->filepos[0]);
-      this->filepos = xrealloc (this->filepos, nbytes);
-      pp = &this->filepos[this->filepos_count++];
-      pp->file_name = xstrdup (name);
-      pp->line_number = line;
-    }
+  size_t nbytes;
+  lex_pos_ty *pp;
+
+  nbytes = (this->filepos_count + 1) * sizeof (this->filepos[0]);
+  this->filepos = xrealloc (this->filepos, nbytes);
+  pp = &this->filepos[this->filepos_count++];
+  pp->file_name = xstrdup (name);
+  pp->line_number = line;
 }
 
 
@@ -458,10 +444,6 @@ default_catalog_reader_alloc 
(default_catalog_reader_class_ty *method_table)
 /* Exported functions.  */
 
 
-/* If nonzero, remember comments for file name and line number for each
-   msgid, if present in the reference input.  Defaults to true.  */
-int line_comment = 1;
-
 /* If false, duplicate msgids in the same domain and file generate an error.
    If true, such msgids are allowed; the caller should treat them
    appropriately.  Defaults to false.  */
@@ -478,7 +460,6 @@ read_catalog_stream (FILE *fp, const char *real_filename,
 
   pop = default_catalog_reader_alloc (&default_methods);
   pop->handle_comments = true;
-  pop->handle_filepos_comments = (line_comment != 0);
   pop->allow_domain_directives = true;
   pop->allow_duplicates = allow_duplicates;
   pop->allow_duplicates_if_same_msgstr = false;
diff --git a/gettext-tools/src/read-catalog.h b/gettext-tools/src/read-catalog.h
index 8b77014..f567d78 100644
--- a/gettext-tools/src/read-catalog.h
+++ b/gettext-tools/src/read-catalog.h
@@ -77,10 +77,6 @@ struct default_catalog_reader_class_ty
   /* If true, pay attention to comments and filepos comments.  */       \
   bool handle_comments;                                                 \
                                                                         \
-  /* If true, remember comments for file name and line number for each  \
-     msgid, if present in the reference input.  */                      \
-  bool handle_filepos_comments;                                         \
-                                                                        \
   /* If false, domain directives lead to an error messsage.  */         \
   bool allow_domain_directives;                                         \
                                                                         \
@@ -167,10 +163,6 @@ extern default_catalog_reader_ty *
        default_catalog_reader_alloc (default_catalog_reader_class_ty 
*method_table);
 
 
-/* If nonzero, remember comments for file name and line number for each
-   msgid, if present in the reference input.  Defaults to true.  */
-extern DLL_VARIABLE int line_comment;
-
 /* If false, duplicate msgids in the same domain and file generate an error.
    If true, such msgids are allowed; the caller should treat them
    appropriately.  Defaults to false.  */
diff --git a/gettext-tools/src/write-po.c b/gettext-tools/src/write-po.c
index 8cfd7c4..1534a3b 100644
--- a/gettext-tools/src/write-po.c
+++ b/gettext-tools/src/write-po.c
@@ -306,21 +306,57 @@ message_print_comment_dot (const message_ty *mp, 
ostream_t stream)
 
 /* Output mp->filepos as a set of comment lines.  */
 
+static enum filepos_comment_type filepos_comment_type = filepos_comment_full;
+
 void
 message_print_comment_filepos (const message_ty *mp, ostream_t stream,
                                bool uniforum, size_t page_width)
 {
-  if (mp->filepos_count != 0)
+  if (filepos_comment_type != filepos_comment_none
+      && mp->filepos_count != 0)
     {
+      size_t filepos_count;
+      lex_pos_ty *filepos;
+
       begin_css_class (stream, class_reference_comment);
 
+      if (filepos_comment_type == filepos_comment_file)
+        {
+          size_t i;
+
+          filepos_count = 0;
+          filepos = XNMALLOC (mp->filepos_count, lex_pos_ty);
+
+          for (i = 0; i < mp->filepos_count; ++i)
+            {
+              lex_pos_ty *pp = &mp->filepos[i];
+              size_t j;
+
+              for (j = 0; j < filepos_count; j++)
+                if (strcmp (filepos[j].file_name, pp->file_name) == 0)
+                  break;
+
+              if (j == filepos_count)
+                {
+                  filepos[filepos_count].file_name = pp->file_name;
+                  filepos[filepos_count].line_number = (size_t)-1;
+                  filepos_count++;
+                }
+            }
+        }
+      else
+        {
+          filepos = mp->filepos;
+          filepos_count = mp->filepos_count;
+        }
+
       if (uniforum)
         {
           size_t j;
 
-          for (j = 0; j < mp->filepos_count; ++j)
+          for (j = 0; j < filepos_count; ++j)
             {
-              lex_pos_ty *pp = &mp->filepos[j];
+              lex_pos_ty *pp = &filepos[j];
               const char *cp = pp->file_name;
               char *str;
 
@@ -345,19 +381,21 @@ message_print_comment_filepos (const message_ty *mp, 
ostream_t stream,
 
           ostream_write_str (stream, "#:");
           column = 2;
-          for (j = 0; j < mp->filepos_count; ++j)
+          for (j = 0; j < filepos_count; ++j)
             {
               lex_pos_ty *pp;
               char buffer[21];
               const char *cp;
               size_t len;
 
-              pp = &mp->filepos[j];
+              pp = &filepos[j];
               cp = pp->file_name;
               while (cp[0] == '.' && cp[1] == '/')
                 cp += 2;
-              /* Some xgettext input formats, like RST, lack line numbers.  */
-              if (pp->line_number == (size_t)(-1))
+              if (filepos_comment_type == filepos_comment_file
+                  /* Some xgettext input formats, like RST, lack line
+                     numbers.  */
+                  || pp->line_number == (size_t)(-1))
                 buffer[0] = '\0';
               else
                 sprintf (buffer, ":%ld", (long) pp->line_number);
@@ -377,6 +415,9 @@ message_print_comment_filepos (const message_ty *mp, 
ostream_t stream,
           ostream_write_str (stream, "\n");
         }
 
+      if (filepos != mp->filepos)
+        free (filepos);
+
       end_css_class (stream, class_reference_comment);
     }
 }
@@ -505,6 +546,37 @@ message_print_style_escape (bool flag)
   escape = flag;
 }
 
+void
+message_print_style_filepos (enum filepos_comment_type type)
+{
+  filepos_comment_type = type;
+}
+
+
+/* --add-location argument handling.  Return an error indicator.  */
+bool
+handle_filepos_comment_option (const char *option)
+{
+  if (option != NULL)
+    {
+      if (strcmp (option, "never") == 0 || strcmp (option, "no") == 0)
+        message_print_style_filepos (filepos_comment_none);
+      else if (strcmp (option, "full") == 0 || strcmp (option, "yes") == 0)
+        message_print_style_filepos (filepos_comment_full);
+      else if (strcmp (option, "file") == 0)
+        message_print_style_filepos (filepos_comment_file);
+      else
+        {
+          fprintf (stderr, "invalid --add-location argument: %s\n", option);
+          return true;
+        }
+    }
+  else
+    /* --add-location is equivalent to --add-location=full.  */
+    message_print_style_filepos (filepos_comment_full);
+  return false;
+}
+
 
 /* =============== msgdomain_list_print_po() and subroutines. =============== 
*/
 
diff --git a/gettext-tools/src/write-po.h b/gettext-tools/src/write-po.h
index 01875a5..9a243bf 100644
--- a/gettext-tools/src/write-po.h
+++ b/gettext-tools/src/write-po.h
@@ -30,6 +30,13 @@ extern "C" {
 #endif
 
 
+enum filepos_comment_type
+  {
+    filepos_comment_none,
+    filepos_comment_full,
+    filepos_comment_file
+  };
+
 /* These functions are used to output a #, flags line.  */
 extern const char *
        make_format_description_string (enum is_format is_format,
@@ -61,6 +68,12 @@ extern void
        message_print_style_uniforum (void);
 extern void
        message_print_style_escape (bool flag);
+extern void
+       message_print_style_filepos (enum filepos_comment_type type);
+
+/* --add-location argument handling.  Return an error indicator.  */
+extern bool handle_filepos_comment_option (const char *option);
+
 
 /* Describes a PO file in .po syntax.  */
 extern DLL_VARIABLE const struct catalog_output_format output_format_po;
diff --git a/gettext-tools/src/x-po.c b/gettext-tools/src/x-po.c
index aecf595..89824e2 100644
--- a/gettext-tools/src/x-po.c
+++ b/gettext-tools/src/x-po.c
@@ -155,7 +155,6 @@ extract (FILE *fp,
 
   pop = default_catalog_reader_alloc (&extract_methods);
   pop->handle_comments = true;
-  pop->handle_filepos_comments = (line_comment != 0);
   pop->allow_domain_directives = false;
   pop->allow_duplicates = false;
   pop->allow_duplicates_if_same_msgstr = true;
diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c
index 8e89a33..8f14b93 100644
--- a/gettext-tools/src/xgettext.c
+++ b/gettext-tools/src/xgettext.c
@@ -199,7 +199,7 @@ iconv_t xgettext_current_source_iconv;
 static const struct option long_options[] =
 {
   { "add-comments", optional_argument, NULL, 'c' },
-  { "add-location", no_argument, &line_comment, 1 },
+  { "add-location", optional_argument, NULL, 'n' },
   { "boost", no_argument, NULL, CHAR_MAX + 11 },
   { "c++", no_argument, NULL, 'C' },
   { "color", optional_argument, NULL, CHAR_MAX + 14 },
@@ -225,7 +225,7 @@ static const struct option long_options[] =
   { "msgstr-prefix", optional_argument, NULL, 'm' },
   { "msgstr-suffix", optional_argument, NULL, 'M' },
   { "no-escape", no_argument, NULL, 'e' },
-  { "no-location", no_argument, &line_comment, 0 },
+  { "no-location", no_argument, NULL, CHAR_MAX + 16 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 4 },
   { "omit-header", no_argument, &xgettext_omit_header, 1 },
   { "output", required_argument, NULL, 'o' },
@@ -473,7 +473,8 @@ main (int argc, char *argv[])
         break;
 
       case 'n':
-        line_comment = 1;
+        if (handle_filepos_comment_option (optarg))
+          usage (EXIT_FAILURE);
         break;
 
       case 'o':
@@ -587,6 +588,10 @@ main (int argc, char *argv[])
         handle_style_option (optarg);
         break;
 
+      case CHAR_MAX + 16: /* --no-location */
+        message_print_style_filepos (filepos_comment_none);
+        break;
+
       default:
         usage (EXIT_FAILURE);
         /* NOTREACHED */
@@ -612,10 +617,6 @@ There is NO WARRANTY, to the extent permitted by law.\n\
     usage (EXIT_SUCCESS);
 
   /* Verify selected options.  */
-  if (!line_comment && sort_by_filepos)
-    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
-           "--no-location", "--sort-by-file");
-
   if (sort_by_msgid && sort_by_filepos)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--sort-output", "--sort-by-file");
@@ -2474,8 +2475,7 @@ meta information, not the empty string.\n")));
   warn_format_string (is_format, mp->msgid, pos, "msgid");
 
   /* Remember where we saw this msgid.  */
-  if (line_comment)
-    message_comment_filepos (mp, pos->file_name, pos->line_number);
+  message_comment_filepos (mp, pos->file_name, pos->line_number);
 
   /* Tell the lexer to reset its comment buffer, so that the next
      message gets the correct comments.  */
diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog
index 85fe091..1ecaf8f 100644
--- a/gettext-tools/tests/ChangeLog
+++ b/gettext-tools/tests/ChangeLog
@@ -1,3 +1,18 @@
+2014-03-25  Daiki Ueno  <address@hidden>
+
+       Add tests for --add-location=file option.
+       * msgattrib-18: New file.
+       * msgcat-19: New file.
+       * msgcomm-28: New file.
+       * msgconv-7: New file.
+       * msgen-4: New file.
+       * msgfilter-5: New file.
+       * msggrep-11: New file.
+       * msgmerge-25: New file.
+       * msguniq-7: New file.
+       * xgettext-10: New file.
+       * Makefile.am (TESTS): Add new tests
+
 2014-03-11  Daiki Ueno  <address@hidden>
 
        * Makefile.am (EXTRA_DIST): Add init.cfg, which is no longer
diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am
index e90bec4..39f5612 100644
--- a/gettext-tools/tests/Makefile.am
+++ b/gettext-tools/tests/Makefile.am
@@ -25,11 +25,11 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 
gettext-6 gettext-7 \
        msgattrib-1 msgattrib-2 msgattrib-3 msgattrib-4 msgattrib-5 \
        msgattrib-6 msgattrib-7 msgattrib-8 msgattrib-9 msgattrib-10 \
        msgattrib-11 msgattrib-12 msgattrib-13 msgattrib-14 msgattrib-15 \
-       msgattrib-16 msgattrib-17 \
+       msgattrib-16 msgattrib-17 msgattrib-18 \
        msgattrib-properties-1 \
        msgcat-1 msgcat-2 msgcat-3 msgcat-4 msgcat-5 msgcat-6 msgcat-7 \
        msgcat-8 msgcat-9 msgcat-10 msgcat-11 msgcat-12 msgcat-13 msgcat-14 \
-       msgcat-15 msgcat-16 msgcat-17 msgcat-18 \
+       msgcat-15 msgcat-16 msgcat-17 msgcat-18 msgcat-19 \
        msgcat-properties-1 msgcat-properties-2 \
        msgcat-stringtable-1 \
        msgcmp-1 msgcmp-2 msgcmp-3 msgcmp-4 \
@@ -37,11 +37,11 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 
gettext-6 gettext-7 \
        msgcomm-8 msgcomm-9 msgcomm-10 msgcomm-11 msgcomm-12 msgcomm-13 \
        msgcomm-14 msgcomm-15 msgcomm-16 msgcomm-17 msgcomm-18 msgcomm-19 \
        msgcomm-20 msgcomm-21 msgcomm-22 msgcomm-23 msgcomm-24 msgcomm-25 \
-       msgcomm-26 msgcomm-27 \
-       msgconv-1 msgconv-2 msgconv-3 msgconv-4 msgconv-5 msgconv-6 \
-       msgen-1 msgen-2 msgen-3 \
+       msgcomm-26 msgcomm-27 msgcomm-28 \
+       msgconv-1 msgconv-2 msgconv-3 msgconv-4 msgconv-5 msgconv-6 msgconv-7 \
+       msgen-1 msgen-2 msgen-3 msgen-4 \
        msgexec-1 msgexec-2 msgexec-3 msgexec-4 \
-       msgfilter-1 msgfilter-2 msgfilter-3 msgfilter-4 \
+       msgfilter-1 msgfilter-2 msgfilter-3 msgfilter-4 msgfilter-5 \
        msgfilter-sr-latin-1 \
        msgfmt-1 msgfmt-2 msgfmt-3 msgfmt-4 msgfmt-5 msgfmt-6 msgfmt-7 \
        msgfmt-8 msgfmt-9 msgfmt-10 msgfmt-11 msgfmt-12 msgfmt-13 msgfmt-14 \
@@ -49,13 +49,13 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 
gettext-6 gettext-7 \
        msgfmt-properties-1 \
        msgfmt-qt-1 msgfmt-qt-2 \
        msggrep-1 msggrep-2 msggrep-3 msggrep-4 msggrep-5 msggrep-6 msggrep-7 \
-       msggrep-8 msggrep-9 msggrep-10 \
+       msggrep-8 msggrep-9 msggrep-10 msggrep-11 \
        msginit-1 msginit-2 \
        msgmerge-1 msgmerge-2 msgmerge-3 msgmerge-4 msgmerge-5 msgmerge-6 \
        msgmerge-7 msgmerge-8 msgmerge-9 msgmerge-10 msgmerge-11 msgmerge-12 \
        msgmerge-13 msgmerge-14 msgmerge-15 msgmerge-16 msgmerge-17 \
        msgmerge-18 msgmerge-19 msgmerge-20 msgmerge-21 msgmerge-22 \
-       msgmerge-23 msgmerge-24 \
+       msgmerge-23 msgmerge-24 msgmerge-25 \
        msgmerge-compendium-1 msgmerge-compendium-2 msgmerge-compendium-3 \
        msgmerge-compendium-4 msgmerge-compendium-5 msgmerge-compendium-6 \
        msgmerge-properties-1 msgmerge-properties-2 \
@@ -66,10 +66,10 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 
gettext-6 gettext-7 \
        msgunfmt-java-1 \
        msgunfmt-properties-1 \
        msgunfmt-tcl-1 \
-       msguniq-1 msguniq-2 msguniq-3 msguniq-4 msguniq-5 msguniq-6 \
+       msguniq-1 msguniq-2 msguniq-3 msguniq-4 msguniq-5 msguniq-6 msguniq-7 \
        recode-sr-latin-1 recode-sr-latin-2 \
        xgettext-1 xgettext-2 xgettext-3 xgettext-4 xgettext-5 xgettext-6 \
-       xgettext-7 xgettext-8 xgettext-9 \
+       xgettext-7 xgettext-8 xgettext-9 xgettext-10 \
        xgettext-awk-1 xgettext-awk-2 \
        xgettext-c-1 xgettext-c-2 xgettext-c-3 xgettext-c-4 xgettext-c-5 \
        xgettext-c-6 xgettext-c-7 xgettext-c-8 xgettext-c-9 xgettext-c-10 \
diff --git a/gettext-tools/tests/msgattrib-18 b/gettext-tools/tests/msgattrib-18
new file mode 100755
index 0000000..68be0f2
--- /dev/null
+++ b/gettext-tools/tests/msgattrib-18
@@ -0,0 +1,98 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<\EOF > ma-test18.po
+# HEADER.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Bonnie Tyler\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: married-men:4
+#, fuzzy
+msgid "The world is full of married men"
+msgstr "So viele verheiratete M�nner"
+
+#: married-men:5
+msgid "with wives who never understand"
+msgstr "und ihre Frauen verstehen sie nicht"
+
+#: married-men:6
+msgid "They're looking for someone to share"
+msgstr ""
+
+# schwer zu �bersetzen...
+#: married-men:7
+msgid "the excitement of a love affair"
+msgstr ""
+
+#: married-men:8
+msgid "Just as soon as they find you"
+msgstr ""
+
+#: married-men:9
+msgid "They warn you and darn you"
+msgstr ""
+
+#~ msgid "You fly on the wings of romance"
+#~ msgstr "Die Fl�gel der frischen Liebe heben dich zum Himmel"
+
+#, fuzzy
+#~ msgid "In the eyes of the world"
+#~ msgstr "F�r die anderen"
+
+# Etwas freie �bersetzung.
+#~ msgid "You're just another crazy girl"
+#~ msgstr "bist du blo� ein verr�cktes dummes Ding"
+
+#~ msgid "Who loves a married man"
+#~ msgstr "das einen verheirateten Mann liebt"
+EOF
+
+: ${MSGATTRIB=msgattrib}
+${MSGATTRIB} --translated --add-location=file -o ma-test18.tmp ma-test18.po \
+    || exit 1
+LC_ALL=C tr -d '\r' < ma-test18.tmp > ma-test18.out || exit 1
+
+cat <<\EOF > ma-test18.ok
+# HEADER.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Bonnie Tyler\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: married-men
+#, fuzzy
+msgid "The world is full of married men"
+msgstr "So viele verheiratete M�nner"
+
+#: married-men
+msgid "with wives who never understand"
+msgstr "und ihre Frauen verstehen sie nicht"
+
+#~ msgid "You fly on the wings of romance"
+#~ msgstr "Die Fl�gel der frischen Liebe heben dich zum Himmel"
+
+#, fuzzy
+#~ msgid "In the eyes of the world"
+#~ msgstr "F�r die anderen"
+
+# Etwas freie �bersetzung.
+#~ msgid "You're just another crazy girl"
+#~ msgstr "bist du blo� ein verr�cktes dummes Ding"
+
+#~ msgid "Who loves a married man"
+#~ msgstr "das einen verheirateten Mann liebt"
+EOF
+
+: ${DIFF=diff}
+${DIFF} ma-test18.ok ma-test18.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msgcat-19 b/gettext-tools/tests/msgcat-19
new file mode 100755
index 0000000..4dd2a40
--- /dev/null
+++ b/gettext-tools/tests/msgcat-19
@@ -0,0 +1,66 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<EOF > mcat-test19.in1
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU one 1.2.3\n"
+"POT-Creation-Date: 2000-12-11 20:49+0100\n"
+"PO-Revision-Date: 2000-03-18 15:25+01:00\n"
+"Last-Translator: Karl Eichwalder <address@hidden>\n"
+"Language-Team: German <address@hidden>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: first.c:123
+msgid "1"
+msgstr "eins"
+EOF
+
+cat <<EOF > mcat-test19.in2
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU one 1.2.3\n"
+"POT-Creation-Date: 2000-12-11 20:49+0100\n"
+"PO-Revision-Date: 2000-03-18 15:25+01:00\n"
+"Last-Translator: Karl Eichwalder <address@hidden>\n"
+"Language-Team: German <address@hidden>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: hunt.c:759
+msgid "1"
+msgstr "eins"
+EOF
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --add-location=file \
+          -o mcat-test19.tmp mcat-test19.in1 mcat-test19.in2 || exit 1
+LC_ALL=C tr -d '\r' < mcat-test19.tmp > mcat-test19.out || exit 1
+
+cat << EOF > mcat-test19.ok
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU one 1.2.3\n"
+"POT-Creation-Date: 2000-12-11 20:49+0100\n"
+"PO-Revision-Date: 2000-03-18 15:25+01:00\n"
+"Last-Translator: Karl Eichwalder <address@hidden>\n"
+"Language-Team: German <address@hidden>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: first.c hunt.c
+msgid "1"
+msgstr "eins"
+EOF
+
+: ${DIFF=diff}
+${DIFF} mcat-test19.ok mcat-test19.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msgcomm-28 b/gettext-tools/tests/msgcomm-28
new file mode 100755
index 0000000..665ab0a
--- /dev/null
+++ b/gettext-tools/tests/msgcomm-28
@@ -0,0 +1,37 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<EOF > mcomm-test28.in1
+#: first.c:123
+msgid "1"
+msgstr "1x"
+EOF
+
+cat <<EOF > mcomm-test28.in2
+#: hunt.c:759
+msgid "2"
+msgstr "2x"
+EOF
+
+: ${MSGCOMM=msgcomm}
+${MSGCOMM} --add-location=file --more-than=0 \
+           -o mcomm-test28.tmp mcomm-test28.in1 mcomm-test28.in2 || exit 1
+LC_ALL=C tr -d '\r' < mcomm-test28.tmp > mcomm-test28.out || exit 1
+
+cat << EOF > mcomm-test28.ok
+#: first.c
+msgid "1"
+msgstr "1x"
+
+#: hunt.c
+msgid "2"
+msgstr "2x"
+EOF
+
+: ${DIFF=diff}
+${DIFF} mcomm-test28.ok mcomm-test28.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msgconv-7 b/gettext-tools/tests/msgconv-7
new file mode 100755
index 0000000..2d1fa65
--- /dev/null
+++ b/gettext-tools/tests/msgconv-7
@@ -0,0 +1,43 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<\EOF > mco-test7.po
+# Chinese translation for GNU gettext messages.
+#
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=big5\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/msgcmp.c:155 src/msgmerge.c:273
+msgid "exactly 2 input files required"
+msgstr "���\���ݭn���n���w���ӿ��J��"
+EOF
+
+: ${MSGCONV=msgconv}
+${MSGCONV} --add-location=file --to-code=UTF-8 \
+           -o mco-test7.out mco-test7.po || exit 1
+
+cat <<\EOF > mco-test7.ok
+# Chinese translation for GNU gettext messages.
+#
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/msgcmp.c src/msgmerge.c
+msgid "exactly 2 input files required"
+msgstr "此功能需要恰好指定兩個輸入檔"
+EOF
+
+: ${DIFF=diff}
+# Redirect stdout, so as not to fill the user's screen with non-ASCII bytes.
+${DIFF} mco-test7.ok mco-test7.out >/dev/null
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msgen-4 b/gettext-tools/tests/msgen-4
new file mode 100755
index 0000000..6dddf5d
--- /dev/null
+++ b/gettext-tools/tests/msgen-4
@@ -0,0 +1,68 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<EOF > men-test1.po
+# HEADER.
+#
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: foo:1
+msgid "height must be positive"
+msgstr ""
+
+#: foo:2
+msgid "color cannot be transparent"
+msgstr "colour cannot be transparent"
+
+#: bar:3
+msgid "width must be positive"
+msgstr ""
+
+#: baz:4
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] ""
+msgstr[1] ""
+EOF
+
+: ${MSGEN=msgen}
+${MSGEN} --add-location=file -o men-test1.tmp men-test1.po || exit 1
+LC_ALL=C tr -d '\r' < men-test1.tmp > men-test1.out || exit 1
+
+cat <<EOF > men-test1.ok
+# HEADER.
+#
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: foo
+msgid "height must be positive"
+msgstr "height must be positive"
+
+#: foo
+msgid "color cannot be transparent"
+msgstr "colour cannot be transparent"
+
+#: bar
+msgid "width must be positive"
+msgstr "width must be positive"
+
+#: baz
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] "%d error"
+msgstr[1] "%d errors"
+EOF
+
+: ${DIFF=diff}
+${DIFF} men-test1.ok men-test1.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msgfilter-5 b/gettext-tools/tests/msgfilter-5
new file mode 100755
index 0000000..0a8da6f
--- /dev/null
+++ b/gettext-tools/tests/msgfilter-5
@@ -0,0 +1,169 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says address@hidden
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='        '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+# Some fold programs (like SunOS4 and FreeBSD) don't have an option to wrap at
+# spaces.
+echo abc | fold -b -s -w 20 >/dev/null 2>&1 || {
+  echo "Skipping test: fold program not POSIX compliant"
+  exit 77
+}
+
+# Some fold programs (like NetBSD 5.0) remove trailing spaces when wrapping.
+echo ab cd | fold -b -s -w 3 | grep ' ' >/dev/null || {
+  echo "Skipping test: fold program trims trailing spaces"
+  exit 77
+}
+
+# Some fold programs (like HP-UX) insert a newline at the end, if the last
+# line was not terminated with a newline and the -s option was given.
+foldoutputcount=`echo $ac_n "abc$ac_c" | fold -b -s -w 20 | wc -c`
+foldoutputcount=`echo "$foldoutputcount" | sed -e 's/[         ]//g'`
+test "$foldoutputcount" = 3 || {
+  echo "Skipping test: fold program inserts extra newline"
+  exit 77
+}
+
+cat <<\EOF > mfi-test5.po
+# HEADER.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Bonnie Tyler\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: married-men:4
+#, fuzzy
+msgid "The world is full of married men"
+msgstr "So viele verheiratete M�nner"
+
+#: married-men:5
+msgid "with wives who never understand"
+msgstr "und ihre Frauen verstehen sie nicht"
+
+#: married-men:6
+msgid "They're looking for someone to share"
+msgstr ""
+
+# schwer zu �bersetzen...
+#: married-men:7
+msgid "the excitement of a love affair"
+msgstr ""
+
+#: married-men:8
+msgid "Just as soon as they find you"
+msgstr ""
+
+#: married-men:9
+msgid "They warn you and darn you"
+msgstr ""
+
+#~ msgid "You fly on the wings of romance"
+#~ msgstr "Die Fl�gel der frischen Liebe heben dich zum Himmel"
+
+#, fuzzy
+#~ msgid "In the eyes of the world"
+#~ msgstr "F�r die anderen"
+
+# Etwas freie �bersetzung.
+#~ msgid "You're just another crazy girl"
+#~ msgstr "bist du blo� ein verr�cktes dummes Ding"
+
+#~ msgid "Who loves a married man"
+#~ msgstr "das einen verheirateten Mann liebt"
+EOF
+
+: ${MSGFILTER=msgfilter}
+LC_ALL=C ${MSGFILTER} --add-location=file -i mfi-test5.po -o mfi-test5.out \
+      fold -b -s -w 20 >mfi-test5.err 2>&1
+result=$?
+cat mfi-test5.err | grep -v 'warning: Locale charset' | grep -v '^ '
+test $result = 0 || { exit 1; }
+
+cat <<\EOF > mfi-test5.ok
+# HEADER.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Bonnie Tyler\n"
+"Content-Type: \n"
+"text/plain; \n"
+"charset=ISO-8859-1\n"
+"Content-Transfer-Enc\n"
+"oding: 8bit\n"
+
+#: married-men
+#, fuzzy
+msgid "The world is full of married men"
+msgstr ""
+"So viele \n"
+"verheiratete M�nner"
+
+#: married-men
+msgid "with wives who never understand"
+msgstr ""
+"und ihre Frauen \n"
+"verstehen sie nicht"
+
+#: married-men
+msgid "They're looking for someone to share"
+msgstr ""
+
+# schwer zu �bersetzen...
+#: married-men
+msgid "the excitement of a love affair"
+msgstr ""
+
+#: married-men
+msgid "Just as soon as they find you"
+msgstr ""
+
+#: married-men
+msgid "They warn you and darn you"
+msgstr ""
+
+#~ msgid "You fly on the wings of romance"
+#~ msgstr ""
+#~ "Die Fl�gel der \n"
+#~ "frischen Liebe \n"
+#~ "heben dich zum \n"
+#~ "Himmel"
+
+#, fuzzy
+#~ msgid "In the eyes of the world"
+#~ msgstr "F�r die anderen"
+
+# Etwas freie �bersetzung.
+#~ msgid "You're just another crazy girl"
+#~ msgstr ""
+#~ "bist du blo� ein \n"
+#~ "verr�cktes dummes \n"
+#~ "Ding"
+
+#~ msgid "Who loves a married man"
+#~ msgstr ""
+#~ "das einen \n"
+#~ "verheirateten Mann \n"
+#~ "liebt"
+EOF
+
+: ${DIFF=diff}
+${DIFF} mfi-test5.ok mfi-test5.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msggrep-11 b/gettext-tools/tests/msggrep-11
new file mode 100755
index 0000000..bf77675
--- /dev/null
+++ b/gettext-tools/tests/msggrep-11
@@ -0,0 +1,189 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<\EOF > mg-test11.po
+# German translations for GNU gettext package.
+# Copyright (C) 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU gettext 0.11-pre1\n"
+"POT-Creation-Date: 2001-12-08 20:33+0100\n"
+"PO-Revision-Date: 2001-11-04 12:25+0100\n"
+"Last-Translator: Karl Eichwalder <address@hidden>\n"
+"Language-Team: German <address@hidden>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: argmatch.c:141
+#, c-format
+msgid "invalid argument `%s' for `%s'"
+msgstr "ung�ltiges Argument �%s� f�r �%s�"
+
+#: argmatch.c:142
+#, c-format
+msgid "ambiguous argument `%s' for `%s'"
+msgstr "mehrdeutiges Argument �%s� f�r �%s�"
+
+#: argmatch.c:162
+msgid "Valid arguments are:"
+msgstr "G�ltige Argumente sind:"
+
+#: copy-file.c:60
+#, c-format
+msgid "error while opening \"%s\" for reading"
+msgstr "�ffnen der Datei �%s� zum Lesen fehlgeschlagen"
+
+#: copy-file.c:67
+#, c-format
+msgid "cannot open backup file \"%s\" for writing"
+msgstr "�ffnen der Sicherungsdatei �%s� zum Schreiben fehlgeschlagen"
+
+#: copy-file.c:80
+#, c-format
+msgid "error reading \"%s\""
+msgstr "Fehler beim Lesen von �%s�"
+
+#: copy-file.c:86 copy-file.c:90
+#, c-format
+msgid "error writing \"%s\""
+msgstr "Fehler beim Schreiben von �%s�"
+
+#: copy-file.c:92
+#, c-format
+msgid "error after reading \"%s\""
+msgstr "Fehler nach dem Lesen von �%s�"
+
+#: error.c:115
+msgid "Unknown system error"
+msgstr "Unbekannter Systemfehler"
+
+#: execute.c:170 execute.c:205 pipe-bidi.c:156 pipe-bidi.c:191 pipe-in.c:169
+#: pipe-in.c:205 pipe-out.c:169 pipe-out.c:205 wait-process.c:136
+#, c-format
+msgid "%s subprocess failed"
+msgstr "Subprozess %s fehlgeschlagen"
+
+#: getopt.c:691
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: Option �%s� ist mehrdeutig\n"
+
+#: getopt.c:716
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: Option �--%s� erwartet kein Argument\n"
+
+#: getopt.c:721
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: Option �%c%s� erwartet kein Argument\n"
+
+#: getopt.c:739 getopt.c:912
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: Option �%s� erwartet ein Argument\n"
+
+#: getopt.c:768
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: unbekannte Option �--%s�\n"
+
+#: getopt.c:772
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: unbekannte Option �%c%s�\n"
+
+#: getopt.c:798
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: unzul�ssige Option -- %c\n"
+
+#: getopt.c:801
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: ung�ltige Option -- %c\n"
+
+#: getopt.c:831 getopt.c:961
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: Option erwartet ein Argument -- %c\n"
+
+#: getopt.c:878
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: Option �-W %s� ist mehrdeutig\n"
+
+#: getopt.c:896
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: Option �-W %s� erwartet kein Argument\n"
+
+#: javacomp.c:465
+msgid "Java compiler not found, try installing gcj or set $JAVAC"
+msgstr ""
+"Java-Compiler nicht gefunden; bitte �gcj� installieren oder $JAVAC setzen"
+
+#: javaexec.c:404
+msgid "Java virtual machine not found, try installing gij or set $JAVA"
+msgstr ""
+"Virtuelle Java-Maschine nicht gefunden; bitte �gcj� installieren oder\n"
+"$JAVA setzen"
+
+#: obstack.c:474 xerror.c:75 xmalloc.c:56
+msgid "memory exhausted"
+msgstr "virtueller Speicher ersch�pft"
+
+#: pipe-bidi.c:119 pipe-bidi.c:121 pipe-in.c:136 pipe-out.c:136
+msgid "cannot create pipe"
+msgstr "Es ist nicht m�glich, eine Pipe zu erzeugen"
+
+#: wait-process.c:117
+#, c-format
+msgid "%s subprocess"
+msgstr "Subprozess %s"
+
+#: wait-process.c:129
+#, c-format
+msgid "%s subprocess got fatal signal"
+msgstr "Subprozess %s hat ein fatales Signal erhalten"
+EOF
+
+: ${MSGGREP=msggrep}
+${MSGGREP} --add-location=file -N pipe-bidi.c -o mg-test11.tmp mg-test11.po \
+    || exit 1
+LC_ALL=C tr -d '\r' < mg-test11.tmp > mg-test11.out || exit 1
+
+cat <<\EOF > mg-test11.ok
+# German translations for GNU gettext package.
+# Copyright (C) 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU gettext 0.11-pre1\n"
+"POT-Creation-Date: 2001-12-08 20:33+0100\n"
+"PO-Revision-Date: 2001-11-04 12:25+0100\n"
+"Last-Translator: Karl Eichwalder <address@hidden>\n"
+"Language-Team: German <address@hidden>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: execute.c pipe-bidi.c pipe-in.c pipe-out.c wait-process.c
+#, c-format
+msgid "%s subprocess failed"
+msgstr "Subprozess %s fehlgeschlagen"
+
+#: pipe-bidi.c pipe-in.c pipe-out.c
+msgid "cannot create pipe"
+msgstr "Es ist nicht m�glich, eine Pipe zu erzeugen"
+EOF
+
+: ${DIFF=diff}
+${DIFF} mg-test11.ok mg-test11.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msgmerge-25 b/gettext-tools/tests/msgmerge-25
new file mode 100755
index 0000000..d0f2d2c
--- /dev/null
+++ b/gettext-tools/tests/msgmerge-25
@@ -0,0 +1,69 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<EOF > mm-test25.in1
+# first
+#. this should be discarded
+msgid "1"
+msgstr "1x"
+# second
+#: bogus:1
+msgid "2"
+msgstr "this is a really long msgstr "
+       "used to test the wrapping to "
+       "make sure it works after all "
+       "what is a test for if not to test things?"
+# third
+msgid "3"
+msgstr "3z"
+EOF
+
+cat <<EOF > mm-test25.in2
+#. this is the first
+#: snark.c:345
+msgid "1"
+msgstr ""
+#. this is the second
+#: hunt.c:759
+msgid "2"
+msgstr ""
+#. this is the third
+#: boojum.c:300
+msgid "3"
+msgstr ""
+EOF
+
+: ${MSGMERGE=msgmerge}
+${MSGMERGE} --add-location=file -q -o mm-test25.tmp mm-test25.in1 
mm-test25.in2 \
+    || exit 1
+LC_ALL=C tr -d '\r' < mm-test25.tmp > mm-test25.out || exit 1
+
+cat << EOF > mm-test25.ok
+# first
+#. this is the first
+#: snark.c
+msgid "1"
+msgstr "1x"
+
+# second
+#. this is the second
+#: hunt.c
+msgid "2"
+msgstr ""
+"this is a really long msgstr used to test the wrapping to make sure it works "
+"after all what is a test for if not to test things?"
+
+# third
+#. this is the third
+#: boojum.c
+msgid "3"
+msgstr "3z"
+EOF
+
+: ${DIFF=diff}
+${DIFF} mm-test25.ok mm-test25.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/msguniq-7 b/gettext-tools/tests/msguniq-7
new file mode 100755
index 0000000..e9c6fa4
--- /dev/null
+++ b/gettext-tools/tests/msguniq-7
@@ -0,0 +1,31 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<\EOF > msguniq-7.in
+#: foo:1
+msgid "foo"
+msgstr ""
+
+#: bar:1
+msgid "foo"
+msgstr ""
+EOF
+
+: ${MSGUNIQ-msguniq}
+${MSGUNIQ} --add-location=file -w 1000 -u -o msguniq-7.tmp \
+           "$abs_srcdir"/msguniq-a.in || exit 1
+LC_ALL=C tr -d '\r' < msguniq-7.tmp > msguniq-7.out || exit 1
+
+cat <<\EOF > msguniq-7.ok
+#: foo bar
+msgid "foo"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} msguniq-7.ok msguniq-7.out
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/xgettext-10 b/gettext-tools/tests/xgettext-10
new file mode 100755
index 0000000..632a4ee
--- /dev/null
+++ b/gettext-tools/tests/xgettext-10
@@ -0,0 +1,36 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test --add-location=file option.
+
+cat <<\EOF > xg-test10a.c
+gettext ("foo");
+EOF
+
+cat <<\EOF > xg-test10b.c
+gettext ("foo");
+gettext ("bar");
+EOF
+
+: ${XGETTEXT=xgettext}
+${XGETTEXT} --add-location=file --omit-header xg-test10a.c xg-test10b.c \
+            -o xg-test10.out >xg-test10.err 2>&1
+result=$?
+cat xg-test10.err | grep -v 'warning: Charset' | grep -v '^ '
+test $result = 0 || { exit 1; }
+
+cat <<\EOF > xg-test10.ok
+#: xg-test10a.c xg-test10b.c
+msgid "foo"
+msgstr ""
+
+#: xg-test10b.c
+msgid "bar"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-test10.ok xg-test10.out
+result=$?
+
+exit $result
-- 
1.8.4.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]