]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Support Java .properties files as alternative syntax, like PO files.
authorBruno Haible <bruno@clisp.org>
Tue, 29 Apr 2003 10:12:15 +0000 (10:12 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:10:24 +0000 (12:10 +0200)
80 files changed:
NEWS
gettext-tools/doc/ChangeLog
gettext-tools/doc/gettext.texi
gettext-tools/doc/msgattrib.texi
gettext-tools/doc/msgcat.texi
gettext-tools/doc/msgcmp.texi
gettext-tools/doc/msgcomm.texi
gettext-tools/doc/msgconv.texi
gettext-tools/doc/msgen.texi
gettext-tools/doc/msgexec.texi
gettext-tools/doc/msgfilter.texi
gettext-tools/doc/msgfmt.texi
gettext-tools/doc/msggrep.texi
gettext-tools/doc/msginit.texi
gettext-tools/doc/msgmerge.texi
gettext-tools/doc/msgunfmt.texi
gettext-tools/doc/msguniq.texi
gettext-tools/doc/xgettext.texi
gettext-tools/src/ChangeLog
gettext-tools/src/FILES
gettext-tools/src/Makefile.am
gettext-tools/src/Makefile.msvc
gettext-tools/src/Makefile.vms
gettext-tools/src/message.c
gettext-tools/src/message.h
gettext-tools/src/msgattrib.c
gettext-tools/src/msgcat.c
gettext-tools/src/msgcmp.c
gettext-tools/src/msgcomm.c
gettext-tools/src/msgconv.c
gettext-tools/src/msgen.c
gettext-tools/src/msgexec.c
gettext-tools/src/msgfilter.c
gettext-tools/src/msgfmt.c
gettext-tools/src/msggrep.c
gettext-tools/src/msginit.c
gettext-tools/src/msgl-cat.c
gettext-tools/src/msgl-iconv.c
gettext-tools/src/msgmerge.c
gettext-tools/src/msgunfmt.c
gettext-tools/src/msguniq.c
gettext-tools/src/po-gram-gen.y
gettext-tools/src/po-lex.c
gettext-tools/src/read-po-abstract.c
gettext-tools/src/read-po-abstract.h
gettext-tools/src/read-po.c
gettext-tools/src/read-po.h
gettext-tools/src/read-properties.c [new file with mode: 0644]
gettext-tools/src/read-properties.h [new file with mode: 0644]
gettext-tools/src/write-java.c
gettext-tools/src/write-java.h
gettext-tools/src/write-po.c
gettext-tools/src/write-po.h
gettext-tools/src/write-properties.c [new file with mode: 0644]
gettext-tools/src/write-properties.h [new file with mode: 0644]
gettext-tools/src/write-tcl.c
gettext-tools/src/write-tcl.h
gettext-tools/src/x-po.c
gettext-tools/src/x-properties.h [new file with mode: 0644]
gettext-tools/src/xgettext.c
gettext-tools/src/xgettext.h
gettext-tools/tests/ChangeLog
gettext-tools/tests/Makefile.am
gettext-tools/tests/msgattrib-15 [new file with mode: 0755]
gettext-tools/tests/msgcat-11 [new file with mode: 0755]
gettext-tools/tests/msgcat-12 [new file with mode: 0755]
gettext-tools/tests/msgcmp-3 [new file with mode: 0755]
gettext-tools/tests/msgcomm-24 [new file with mode: 0755]
gettext-tools/tests/msgconv-4 [new file with mode: 0755]
gettext-tools/tests/msgen-2 [new file with mode: 0755]
gettext-tools/tests/msgexec-3 [new file with mode: 0755]
gettext-tools/tests/msgfilter-3 [new file with mode: 0755]
gettext-tools/tests/msgfmt-13 [new file with mode: 0755]
gettext-tools/tests/msggrep-6 [new file with mode: 0755]
gettext-tools/tests/msgmerge-23 [new file with mode: 0755]
gettext-tools/tests/msgmerge-24 [new file with mode: 0755]
gettext-tools/tests/msgunfmt-4 [new file with mode: 0755]
gettext-tools/tests/msguniq-4 [new file with mode: 0755]
gettext-tools/tests/msguniq-a.inp [new file with mode: 0644]
gettext-tools/tests/xgettext-24 [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index c195c5d39027b56961fb39f4a626da726cc894bd..8a518f1d24a1fd318d9014e9b2d741c84d84af16 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,13 @@ Version 0.12-pre1 - February 2003
     C format strings in C++. This is needed for proper internationalization
     of C++ programs.
 
+  - Java
+
+    All the tools that manipulate PO files can work with .properties files
+    as well, if given the --properties-input and/or --properties-output
+    option. To create a .properties file from a PO or POT file, use
+    "msgcat --properties-output".
+
   - Smalltalk
 
     xgettext now also supports Smalltalk.
index 96fd1fba21f513f32b3dd67ac6d5c998aab8d956..34d00b1524f27290acf526a4237df9ccb2b938b0 100644 (file)
@@ -1,3 +1,23 @@
+2003-04-22  Bruno Haible  <bruno@clisp.org>
+
+       * gettext.texi (Java): Document how to use .properties files.
+       * msgattrib.texi: Document options -P and -p.
+       * msgcat.texi: Likewise.
+       * msgcomm.texi: Likewise.
+       * msgconv.texi: Likewise.
+       * msgen.texi: Likewise.
+       * msgfilter.texi: Likewise.
+       * msggrep.texi: Likewise.
+       * msginit.texi: Likewise.
+       * msgmerge.texi: Likewise.
+       * msguniq.texi: Likewise.
+       * msgcmp.texI: Document option -P.
+       * msgexec.texi: Likewise.
+       * msgfmt.texi: Likewise.
+       * msgunfmt.texi: Document option -p.
+       * xgettext.texi: Document options -L JavaProperties and
+       --properties-output.
+
 2003-04-22  Bruno Haible  <bruno@clisp.org>
 
        * gettext.texi (Plural forms): Add info about Faroese.
index b35d07669025de60b89b9ff4bd8a4b11ff7296eb..dbcfde499df1d5c8ee1bf18b6bc103528d8624bd 100644 (file)
@@ -7804,10 +7804,25 @@ applications. For example, @code{"file "+filename+" not found"} becomes
 Only after this is done, can the strings be marked and extracted.
 
 GNU gettext uses the native Java internationalization mechanism, namely
-@code{ResourceBundle}s. To convert a PO file to a ResourceBundle, the
-@code{msgfmt} program can be used with the option @code{--java} or
-@code{--java2}. To convert a ResourceBundle back to a PO file, the
-@code{msgunfmt} program can be used with the option @code{--java}.
+@code{ResourceBundle}s. There are two formats of @code{ResourceBundle}s:
+@code{.properties} files and @code{.class} files. The @code{.properties}
+format is a text file which the translators can directly edit, like PO
+files, but which doesn't support plural forms. Whereas the @code{.class}
+format is compiled from @code{.java} source code and can support plural
+forms (provided it is accessed through an appropriate API, see below).
+
+To convert a PO file to a @code{.properties} file, the @code{msgcat}
+program can be used with the option @code{--properties-output}. To convert
+a @code{.properties} file back to a PO file, the @code{msgcat} program
+can be used with the option @code{--properties-input}. All the tools
+that manipulate PO files can work with @code{.properties} files as well,
+if given the @code{--properties-input} and/or @code{--properties-output}
+option.
+
+To convert a PO file to a ResourceBundle class, the @code{msgfmt} program
+can be used with the option @code{--java} or @code{--java2}. To convert a
+ResourceBundle back to a PO file, the @code{msgunfmt} program can be used
+with the option @code{--java}.
 
 Two different programmatic APIs can be used to access ResourceBundles.
 Note that both APIs work with all kinds of ResourceBundles, whether
@@ -7822,9 +7837,10 @@ In particular, its @code{getString} function returns a string translation.
 Note that a missing translation yields a @code{MissingResourceException}.
 
 This has the advantage of being the standard API. And it does not require
-any additional libraries, only the @code{msgfmt} generated @code{.class}
-files. But it cannot do plural handling, even if the resource was generated
-from a PO file with plural handling.
+any additional libraries, only the @code{msgcat} generated @code{.properties}
+files or the @code{msgfmt} generated @code{.class} files. But it cannot do
+plural handling, even if the resource was generated by @code{msgfmt} from
+a PO file with plural handling.
 
 @item
 The @code{gnu.gettext.GettextResource} API.
index 7f7bb232dd67400e0146616733c2db5524485a0f..f4c31702b0d089208b10cbaa07d74d2793d6f28e 100644 (file)
@@ -118,6 +118,18 @@ obsolete messages and makes them non-obsolete.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgattrib} option}
+@opindex --properties-input@r{, @code{msgattrib} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -149,6 +161,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgattrib} option}
+@opindex --properties-output@r{, @code{msgattrib} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgattrib} option}
index 795ced53ff1dc09d4f6a508f3a1b17d4b3815939..0e61e18ba54979900579d81bb5cb2a50be589cda 100644 (file)
@@ -82,6 +82,18 @@ printed.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgcat} option}
+@opindex --properties-input@r{, @code{msgcat} option}
+Assume the input files are Java ResourceBundles in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -124,6 +136,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgcat} option}
+@opindex --properties-output@r{, @code{msgcat} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgcat} option}
index 9091cd4853f1f248e25d297b76e39b9df62fb9cd..80b7eee15bb788f5be2de4af56af1f6b4f844c49 100644 (file)
@@ -42,6 +42,18 @@ Apply @var{ref}.pot to each of the domains in @var{def}.po.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgcmp} option}
+@opindex --properties-input@r{, @code{msgcmp} option}
+Assume the input files are Java ResourceBundles in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Informative output
 
 @table @samp
index 79786193e3176be580e3ad89f8384333345bf15b..0ad42036af2c7ef7fc8f73b59e26bf8e4b7e0a3b 100644 (file)
@@ -80,6 +80,18 @@ printed.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgcomm} option}
+@opindex --properties-input@r{, @code{msgcomm} option}
+Assume the input files are Java ResourceBundles in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -111,6 +123,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgcomm} option}
+@opindex --properties-output@r{, @code{msgcomm} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgcomm} option}
index c850263ef642986bc060997b96ff8b8116e3638e..8148244135a9b7c45b29766d8f2f72ac8e57e256 100644 (file)
@@ -53,6 +53,18 @@ Specify encoding for output.
 
 The default encoding is the current locale's encoding.
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgconv} option}
+@opindex --properties-input@r{, @code{msgconv} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -82,6 +94,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgconv} option}
+@opindex --properties-output@r{, @code{msgconv} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgconv} option}
index fceb8913bba99fc0473f58c811f32612b297a319..bc8e47e8513fe0c75e2d98aafd8f94e398c87e63 100644 (file)
@@ -46,6 +46,18 @@ Write output to specified file.
 The results are written to standard output if no output file is specified
 or if it is @samp{-}.
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgen} option}
+@opindex --properties-input@r{, @code{msgen} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -75,6 +87,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgen} option}
+@opindex --properties-output@r{, @code{msgen} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgen} option}
index e060f0c482bf9eca885d08c36075de9b41145286..7163fa40fa464c7290a9964df2b59e0097294238 100644 (file)
@@ -56,6 +56,18 @@ file will be written relative to the current directory, though.
 
 If no @var{inputfile} is given or if it is @samp{-}, standard input is read.
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgexec} option}
+@opindex --properties-input@r{, @code{msgexec} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Informative output
 
 @table @samp
index 1431c15b777566df0ccf00a5d91c9787f7c81797..3b30525be5627417f726386ced786b95af0e1fde 100644 (file)
@@ -94,6 +94,18 @@ Suppress automatic printing of pattern space.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgfilter} option}
+@opindex --properties-input@r{, @code{msgfilter} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -127,6 +139,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgfilter} option}
+@opindex --properties-output@r{, @code{msgfilter} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgfilter} option}
index 6de0b046bd362c0629515788614c45512dd4e866..1444368565b09d07e0be939e6b10efac66dc3760 100644 (file)
@@ -116,6 +116,18 @@ Specify the base directory of @file{.msg} message catalogs.
 The @samp{-l} and @samp{-d} options are mandatory.  The @file{.msg} file is
 written in the specified directory.
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgfmt} option}
+@opindex --properties-input@r{, @code{msgfmt} option}
+Assume the input files are Java ResourceBundles in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Input file interpretation
 
 @table @samp
index 0e7e19336fc6b1a206dd9f7cc02f6b83133249ad..b8dfe5ff56e2dfd2c2c8ec846971c2ad2d2f4673 100644 (file)
@@ -133,6 +133,18 @@ Ignore case distinctions.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msggrep} option}
+@opindex --properties-input@r{, @code{msggrep} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -160,6 +172,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msggrep} option}
+@opindex --properties-output@r{, @code{msggrep} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msggrep} option}
index 96aa34a87c20b24ce8b19c145484011a988978c0..e2f53917475f576451b4df1079ce3f7756e20685 100644 (file)
@@ -38,6 +38,18 @@ If no output file is given, it depends on the @samp{--locale} option or the
 user's locale setting.  If it is @samp{-}, the results are written to
 standard output.
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msginit} option}
+@opindex --properties-input@r{, @code{msginit} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @table @samp
@@ -54,6 +66,14 @@ of all installed locales.  The default is the user's locale setting.
 Declares that the PO file will not have a human translator and is instead
 automatically generated.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msginit} option}
+@opindex --properties-output@r{, @code{msginit} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msginit} option}
index 1832e85e061b66997219bff6d0ebf991db2092f9..d2830d0730c3971e291ff7ed73d229f95bcf8a1b 100644 (file)
@@ -128,6 +128,18 @@ Do not use fuzzy matching when an exact match is not found.  This may speed
 up the operation considerably.
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msgmerge} option}
+@opindex --properties-input@r{, @code{msgmerge} option}
+Assume the input files are Java ResourceBundles in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -157,6 +169,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgmerge} option}
+@opindex --properties-output@r{, @code{msgmerge} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgmerge} option}
index a0051bbb48338f02ad5d7a7be7a77697212de578..afd4f19bc6fa23c196406b44bd2daf99b53a6674 100644 (file)
@@ -110,6 +110,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msgunfmt} option}
+@opindex --properties-output@r{, @code{msgunfmt} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msgunfmt} option}
index eb3707f016dc6e52b201faf8b9e6b8982f5135dd..42c897ebb164a1318121b9e755f9187feb839a4d 100644 (file)
@@ -66,6 +66,18 @@ Print only unique messages, discard duplicates.
 
 @end table
 
+@subsection Input file syntax
+
+@table @samp
+@item -P
+@itemx --properties-input
+@opindex -P@r{, @code{msguniq} option}
+@opindex --properties-input@r{, @code{msguniq} option}
+Assume the input file is a Java ResourceBundle in Java @code{.properties}
+syntax, not in PO file syntax.
+
+@end table
+
 @subsection Output details
 
 @c --no-escape and --escape omitted on purpose.  They are not useful.
@@ -108,6 +120,14 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item -p
+@itemx --properties-output
+@opindex -p@r{, @code{msguniq} option}
+@opindex --properties-output@r{, @code{msguniq} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{msguniq} option}
index 425672c891bfa0801be6ff224cc9da83b1efced3..959456296390fadeced1e942f6a61f033c219ae5 100644 (file)
@@ -71,7 +71,8 @@ is written to standard output.
 Specifies the language of the input files.  The supported languages
 are @code{C}, @code{C++}, @code{ObjectiveC}, @code{PO}, @code{Python},
 @code{Lisp}, @code{EmacsLisp}, @code{librep}, @code{Smalltalk}, @code{Java},
-@code{awk}, @code{YCP}, @code{Tcl}, @code{PHP}, @code{RST}, @code{Glade}.
+@code{JavaProperties}, @code{awk}, @code{YCP}, @code{Tcl}, @code{PHP},
+@code{RST}, @code{Glade}.
 
 @item -C
 @itemx --c++
@@ -210,6 +211,12 @@ Write out a strict Uniforum conforming PO file.  Note that this
 Uniforum format should be avoided because it doesn't support the
 GNU extensions.
 
+@item --properties-output
+@opindex --properties-output@r{, @code{xgettext} option}
+Write out a Java ResourceBundle in Java @code{.properties} syntax.  Note
+that this file format doesn't support plural forms and silently drops
+obsolete messages.
+
 @item -w @var{number}
 @itemx --width=@var{number}
 @opindex -w@r{, @code{xgettext} option}
index 7fde60e232410be6a0ced86ceffe95d0c642b6f3..6d1948d297810bc3b9d1e76e9d9105851da69fef 100644 (file)
@@ -1,3 +1,124 @@
+2003-04-26  Bruno Haible  <bruno@clisp.org>
+
+       * message.h (msgdomain_list_ty): Add field 'encoding'.
+       * message.c (msgdomain_list_alloc): Initialize it.
+       * read-properties.h: New file.
+       * read-properties.c: New file.
+       * read-po-abstract.h (abstract_po_reader_class_ty): In
+       directive_message field, add force_fuzzy argument.
+       (po_scan_start, po_scan_end): Remove declarations.
+       (input_syntax_ty): New type.
+       (po_callback_message): Add force_fuzzy argument.
+       * read-po-abstract.c (call_directive_message, po_callback_message):
+       Add force_fuzzy argument.
+       (po_scan_start, po_scan_end): Make static.
+       (po_scan): Add support for syntax_properties. Move
+       error_message_count handling to here.
+       (po_callback_message): Move po_lex_charset_set invocation away.
+       * read-po.h (default_po_reader_class_ty): In add_message field, add
+       force_fuzzy argument.
+       (default_directive_message, default_add_message): Add force_fuzzy
+       argument.
+       (inout_syntax): New declaration.
+       * read-po.c (call_add_message): Add force_fuzzy argument.
+       (default_directive_message, default_add_message): Likewise.
+       (input_syntax): New variable.
+       (read_po): Pass input_syntax to po_scan(). Set mdlp->encoding if
+       possible.
+       * po-gram-gen.y: Pass force_fuzzy = false.
+       (do_callback_message): New function. Move po_lex_charset_set
+       invocation to here.
+       * po-lex.c (lex_end): Move error_message_count handling away.
+       * write-properties.h: New file.
+       * write-properties.c: New file.
+       * write-po.h (message_print_syntax_properties): New declaration.
+       * write-po.c (use_syntax_properties): New variable.
+       (message_print_syntax_properties): New function.
+       (msgdomain_list_print_po): New function, extracted from
+       msgdomain_list_print.
+       (msgdomain_list_print): Add check for plural forms. Add support for
+       writing the .properties format.
+       (extract_po): Renamed from extract. 
+       * write-java.h (msgdomain_write_java): Add canon_encoding argument.
+       * write-java.c (msgdomain_write_java): Likewise.
+       * write-tcl.h (msgdomain_write_tcl): Likewise.
+       * write-tcl.c (msgdomain_write_tcl): Likewise.
+       * msgl-cat.c (catenate_msgdomain_list): Use mdlp->encoding if there
+       is no header entry. Set total_mdlp->encoding if possible.
+       * msgl-iconv.c (iconv_msgdomain_list): Use mdlp->encoding if there
+       is no header entry. Set mdlp->encoding.
+       * msgattrib.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msgcat.c (long_options): Add --properties-input/output.
+       (main): Handle them. If option -p is used, convert to UTF-8 and
+       ignore the to_code.
+       (usage): Document options -P and -p.
+       * msgcomm.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msgconv.c (long_options): Add --properties-input/output.
+       (main): Handle them. If option -p is used, ignore the to_code.
+       (usage): Document options -P and -p.
+       * msgen.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msgfilter.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msggrep.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msginit.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msgmerge.c (long_options): Add --properties-input/output.
+       (main): Handle them. In update mode, --properties-input implies
+       --properties-output.
+       (usage): Document options -P and -p.
+       (merge): Set result->encoding if possible.
+       * msguniq.c (long_options): Add --properties-input/output.
+       (main): Handle them.
+       (usage): Document options -P and -p.
+       * msgcmp.c (long_options): Add --properties-input.
+       (main): Handle it.
+       (usage): Document option -P.
+       * msgexec.c (long_options): Add --properties-input.
+       (main): Handle it.
+       (usage): Document option -P.
+       * msgfmt.c (long_options): Add --properties-input.
+       (main): Handle it. Pass the known canon_encoding to
+       msgdomain_write_java and msgdomain_write_tcl.
+       (usage): Document option -P.
+       (msgfmt_add_message): Add force_fuzzy argument.
+       (read_po_file_msgfmt): Pass input_syntax to po_scan().
+       * msgunfmt.c (long_options): Add --properties-output.
+       (main): Handle it.
+       (usage): Document option -p.
+       * x-properties.h: New file.
+       * x-po.c (extract_add_message): Add force_fuzzy argument.
+       (extract): Renamed from extract_po. Pass input_syntax to po_scan().
+       (extract_po): New function.
+       (extract_properties): New function.
+       * xgettext.h: Include read-po.h.
+       * xgettext.c (long_options): Add --properties-output.
+       (main): Handle it.
+       (usage): Document options -L JavaProperties and --properties-output.
+       (exclude_directive_message): Add force_fuzzy argument.
+       (read_exclusion_file): Pass input_syntax to po_scan().
+       (table): Add support for .properties format.
+       * Makefile.am (noinst_HEADERS): Add read-properties.h,
+       write-properties.h, x-properties.h.
+       (COMMON_SOURCE): Add read-properties.c.
+       (libgettextsrc_la_SOURCES): Add write-properties.c.
+       * Makefile.msvc (OBJECTS): Add read-properties.obj,
+       write-properties.obj.
+       (read-properties.obj, write-properties.obj): New rules.
+       * Makefile.vms (OBJECTS): Add read-properties.obj,
+       write-properties.obj.
+       (read-properties.obj, write-properties.obj): New rules.
+       * FILES: Update.
+
 2003-04-21  Bruno Haible  <bruno@clisp.org>
 
        * read-po-abstract.h (po_scan_file): Remove declaration.
index d8b35fa2fa41383c1f3e9ecef48c51a45ffc5e52..6f9c17a0ffd0ea981ffb1beb79530d8955530bf4 100644 (file)
@@ -35,6 +35,9 @@ msgl-ascii.c
 write-po.h
 write-po.c
                 Output of a list-of-messages to a PO file.
+write-properties.h
+write-properties.c
+                Output of a list-of-messages to a Java .properties file.
 
 +-------------- Reading PO files
 | open-po.h
@@ -54,8 +57,10 @@ write-po.c
 | po-hash-gen.y
 | po-gram.h
 | po-gram-gen.y
+| read-properties.h
+| read-properties.c
 | read-po-abstract.c
-|               Parsing of PO files.
+|               Parsing of PO files and Java .properties files.
 |         read-po-abstract.h
 |                       General parser structure.
 |         po-hash.h
@@ -65,6 +70,9 @@ write-po.c
 |         po-gram.h
 |         po-gram-gen.y
 |                       Parsing of PO files, based on po-lex.{h,c}.
+|         read-properties.h
+|         read-properties.c
+|                       Parsing of Java .properties files.
 |         read-po-abstract.c
 |                       Top-level parser functions and callbacks.
 |
index 15103e8227ad827b2f9797ab43284e2cb5901712..4c1d99b9e70c40e7abee93b3b85021125536d539 100644 (file)
@@ -35,13 +35,14 @@ lib_LTLIBRARIES = libgettextsrc.la libgettextpo.la
 include_HEADERS = gettext-po.h
 
 noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-charset.h po-lex.h \
-open-po.h read-po-abstract.h read-po.h str-list.h write-po.h dir-list.h \
-file-list.h po-gram-gen.h po-gram-gen2.h po-hash-gen.h msgl-charset.h \
-msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-english.h msgfmt.h \
-msgunfmt.h read-mo.h write-mo.h read-java.h write-java.h read-tcl.h \
-write-tcl.h po-time.h plural-table.h format.h xgettext.h x-c.h x-po.h \
-x-python.h x-lisp.h x-elisp.h x-librep.h x-smalltalk.h x-java.h x-awk.h \
-x-ycp.h x-tcl.h x-php.h x-rst.h x-glade.h
+open-po.h read-po-abstract.h read-po.h read-properties.h str-list.h \
+write-po.h write-properties.h dir-list.h file-list.h po-gram-gen.h \
+po-gram-gen2.h po-hash-gen.h msgl-charset.h msgl-equal.h msgl-iconv.h \
+msgl-ascii.h msgl-cat.h msgl-english.h msgfmt.h msgunfmt.h read-mo.h \
+write-mo.h read-java.h write-java.h read-tcl.h write-tcl.h po-time.h \
+plural-table.h format.h xgettext.h x-c.h x-po.h x-python.h x-lisp.h x-elisp.h \
+x-librep.h x-smalltalk.h x-java.h x-properties.h x-awk.h x-ycp.h x-tcl.h \
+x-php.h x-rst.h x-glade.h
 
 EXTRA_DIST += FILES project-id ChangeLog.0
 
@@ -86,7 +87,7 @@ JAVACOMP = $(SHELL) ../lib/javacomp.sh
 # (read-po-abstract.c <--> po-hash-gen.y <--> po-gram-gen.y <--> po-lex.c) -> message.c -> str-list.c.
 COMMON_SOURCE = message.c \
 read-po-abstract.c po-lex.c po-gram-gen.y po-hash-gen.y po-charset.c \
-open-po.c dir-list.c str-list.c
+read-properties.c open-po.c dir-list.c str-list.c
 
 # xgettext and msgfmt deal with format strings.
 FORMAT_SOURCE = format.c format-invalid.h \
@@ -96,9 +97,9 @@ format-php.c
 
 # libgettextsrc contains all code that is needed by at least two programs.
 libgettextsrc_la_SOURCES = \
-$(COMMON_SOURCE) read-po.c write-po.c msgl-ascii.c msgl-iconv.c msgl-equal.c \
-msgl-cat.c msgl-english.c file-list.c msgl-charset.c po-time.c plural.c \
-plural-table.c $(FORMAT_SOURCE)
+$(COMMON_SOURCE) read-po.c write-properties.c write-po.c msgl-ascii.c \
+msgl-iconv.c msgl-equal.c msgl-cat.c msgl-english.c file-list.c \
+msgl-charset.c po-time.c plural.c plural-table.c $(FORMAT_SOURCE)
 
 # libgettextpo contains the public API for PO files.
 libgettextpo_la_SOURCES = gettext-po.c
index a824f10f518d49d7cf245c3f92bd410945d19c26..ee93260b545dbbe6ee556806c8baf2b93b70736e 100644 (file)
@@ -109,10 +109,12 @@ OBJECTS = \
   po-gram-gen.obj \
   po-hash-gen.obj \
   po-charset.obj \
+  read-properties.obj \
   open-po.obj \
   dir-list.obj \
   str-list.obj \
   read-po.obj \
+  write-properties.obj \
   write-po.obj \
   msgl-ascii.obj \
   msgl-iconv.obj \
@@ -178,6 +180,9 @@ po-hash-gen.obj : po-hash-gen.c
 po-charset.obj : po-charset.c
        $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c po-charset.c
 
+read-properties.obj : read-properties.c
+       $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c read-properties.c
+
 open-po.obj : open-po.c
        $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c open-po.c
 
@@ -190,6 +195,9 @@ str-list.obj : str-list.c
 read-po.obj : read-po.c
        $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c read-po.c
 
+write-properties.obj : write-properties.c
+       $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c write-properties.c
+
 write-po.obj : write-po.c
        $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c write-po.c
 
index 481c3d3848233789bcfde01a053d4a88179ad002..6c297c3a9f10662d9f878144b47ce7d1c9554e52 100644 (file)
@@ -57,10 +57,12 @@ OBJECTS = \
   po-gram-gen.obj, \
   po-hash-gen.obj, \
   po-charset.obj, \
+  read-properties.obj, \
   open-po.obj, \
   dir-list.obj, \
   str-list.obj, \
   read-po.obj, \
+  write-properties.obj, \
   write-po.obj, \
   msgl-ascii.obj, \
   msgl-iconv.obj, \
@@ -124,6 +126,9 @@ po-hash-gen.obj : po-hash-gen.c
 po-charset.obj : po-charset.c
        $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) po-charset.c
 
+read-properties.obj : read-properties.c
+       $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) read-properties.c
+
 open-po.obj : open-po.c
        $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) open-po.c
 
@@ -136,6 +141,9 @@ str-list.obj : str-list.c
 read-po.obj : read-po.c
        $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) read-po.c
 
+write-properties.obj : write-properties.c
+       $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) write-properties.c
+
 write-po.obj : write-po.c
        $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) write-po.c
 
index 2b9bc575db144d9b59d1538c15e357a47126701c..6306bc18c5c4554d7085f6e354766467d1a43ff8 100644 (file)
@@ -524,6 +524,7 @@ msgdomain_list_alloc (bool use_hashtable)
     (msgdomain_ty **) xmalloc (mdlp->nitems_max * sizeof (msgdomain_ty *));
   mdlp->item[0] = msgdomain_alloc (MESSAGE_DOMAIN_DEFAULT, use_hashtable);
   mdlp->use_hashtable = use_hashtable;
+  mdlp->encoding = NULL;
   return mdlp;
 }
 
index fe506d78910c0bbc7bbda5f1535513099c2241f2..393ede215a5a395d911197b6b10b96186b19e513 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -235,6 +235,7 @@ struct msgdomain_list_ty
   size_t nitems;
   size_t nitems_max;
   bool use_hashtable;
+  const char *encoding;                /* canonicalized encoding or NULL if unknown */
 };
 
 extern msgdomain_list_ty *
index 9b8dab65f79939f4be461e9b1b5f0c387d05b1f1..a394d6fd0182ef8b40543a659beb2d6eed140927 100644 (file)
@@ -89,6 +89,8 @@ static const struct option long_options[] =
   { "only-fuzzy", no_argument, NULL, CHAR_MAX + 4 },
   { "only-obsolete", no_argument, NULL, CHAR_MAX + 6 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "set-fuzzy", no_argument, NULL, CHAR_MAX + 7 },
   { "set-obsolete", no_argument, NULL, CHAR_MAX + 9 },
   { "sort-by-file", no_argument, NULL, 'F' },
@@ -150,7 +152,7 @@ main (int argc, char **argv)
   only_file = NULL;
   ignore_file = NULL;
 
-  while ((optchar = getopt_long (argc, argv, "D:eEFhino:sVw:", long_options,
+  while ((optchar = getopt_long (argc, argv, "D:eEFhino:pPsVw:", long_options,
                                 NULL)) != EOF)
     switch (optchar)
       {
@@ -189,6 +191,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -412,6 +422,11 @@ Attribute manipulation:\n"));
       --obsolete              synonym for --only-obsolete --clear-obsolete\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -e, --no-escape             do not use C escapes in output (default)\n"));
@@ -428,6 +443,8 @@ Output details:\n"));
       printf (_("\
       --strict                write out strict Uniforum conforming .po file\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 4a07bf6a9ba649215373743f0a066bc056e462a1..a4d3e5b5e465922bac37a38f77c7c23bb5dcd53f 100644 (file)
@@ -64,6 +64,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -97,6 +99,7 @@ main (int argc, char **argv)
   const char *files_from;
   string_list_ty *file_list;
   msgdomain_list_ty *result;
+  input_syntax_ty output_syntax = syntax_po;
   bool sort_by_msgid = false;
   bool sort_by_filepos = false;
 
@@ -122,7 +125,7 @@ main (int argc, char **argv)
   less_than = INT_MAX;
   use_first = false;
 
-  while ((optchar = getopt_long (argc, argv, "<:>:D:eEf:Fhino:st:uVw:",
+  while ((optchar = getopt_long (argc, argv, "<:>:D:eEf:Fhino:pPst:uVw:",
                                 long_options, NULL)) != EOF)
     switch (optchar)
       {
@@ -185,6 +188,15 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       output_syntax = syntax_properties;
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -271,7 +283,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
     string_list_append_unique (file_list, argv[cnt]);
 
   /* Read input files, then filter, convert and merge messages.  */
-  result = catenate_msgdomain_list (file_list, to_code);
+  result = catenate_msgdomain_list (file_list,
+                                   output_syntax != syntax_properties
+                                   ? to_code
+                                   : "UTF-8");
 
   string_list_free (file_list);
 
@@ -349,6 +364,11 @@ Message selection:\n"));
                               that only unique messages be printed\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input files are in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -t, --to-code=NAME          encoding for output\n"));
@@ -370,6 +390,8 @@ Output details:\n"));
       printf (_("\
       --strict                write out strict Uniforum conforming .po file\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 6f627a36a20020afc01c6de5b6fe1aa30df0f4e1..c26f0f780047c55aaa936895de94b166f364a7c4 100644 (file)
@@ -52,6 +52,7 @@ static const struct option long_options[] =
   { "directory", required_argument, NULL, 'D' },
   { "help", no_argument, NULL, 'h' },
   { "multi-domain", no_argument, NULL, 'm' },
+  { "properties-input", no_argument, NULL, 'P' },
   { "version", no_argument, NULL, 'V' },
   { NULL, 0, NULL, 0 }
 };
@@ -89,7 +90,7 @@ main (int argc, char *argv[])
 
   do_help = false;
   do_version = false;
-  while ((optchar = getopt_long (argc, argv, "D:hmV", long_options, NULL))
+  while ((optchar = getopt_long (argc, argv, "D:hmPV", long_options, NULL))
         != EOF)
     switch (optchar)
       {
@@ -108,6 +109,10 @@ main (int argc, char *argv[])
        multi_domain_mode = true;
        break;
 
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 'V':
        do_version = true;
        break;
@@ -194,6 +199,11 @@ Operation modifiers:\n"));
   -m, --multi-domain          apply ref.pot to each of the domains in def.po\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input files are in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Informative output:\n"));
       printf (_("\
   -h, --help                  display this help and exit\n"));
index 0b8219337c0fd27bc44a1785a1fc7dadf9533be3..329540994034d2876378a0d89263c629df0e135d 100644 (file)
@@ -68,6 +68,8 @@ static const struct option long_options[] =
   { "omit-header", no_argument, NULL, CHAR_MAX + 1 },
   { "output", required_argument, NULL, 'o' }, /* for backward compatibility */
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -121,7 +123,7 @@ main (int argc, char *argv[])
   less_than = -1;
   use_first = false;
 
-  while ((optchar = getopt_long (argc, argv, "<:>:D:eEf:Fhino:st:uVw:",
+  while ((optchar = getopt_long (argc, argv, "<:>:D:eEf:Fhino:pPst:uVw:",
                                 long_options, NULL)) != EOF)
     switch (optchar)
       {
@@ -184,6 +186,14 @@ main (int argc, char *argv[])
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -360,6 +370,11 @@ Message selection:\n"));
                               that only unique messages be printed\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input files are in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -e, --no-escape             do not use C escapes in output (default)\n"));
@@ -376,6 +391,8 @@ Output details:\n"));
       printf (_("\
       --strict                write out strict Uniforum conforming .po file\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 41a0b8ae047db5725b3f2f25b71a32a4ba13d753..1929e8cec04896dd4c99bf52c6283a8d8b44516d 100644 (file)
@@ -62,6 +62,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 1 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -89,6 +91,7 @@ main (int argc, char **argv)
   char *output_file;
   const char *input_file;
   msgdomain_list_ty *result;
+  input_syntax_ty output_syntax = syntax_po;
   bool sort_by_filepos = false;
   bool sort_by_msgid = false;
 
@@ -111,7 +114,8 @@ main (int argc, char **argv)
   output_file = NULL;
   input_file = NULL;
 
-  while ((opt = getopt_long (argc, argv, "D:eEFhio:st:Vw:", long_options, NULL))
+  while ((opt = getopt_long (argc, argv, "D:eEFhio:pPst:Vw:", long_options,
+                            NULL))
         != EOF)
     switch (opt)
       {
@@ -146,6 +150,15 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       output_syntax = syntax_properties;
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -223,9 +236,12 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
   if (to_code == NULL)
     to_code = locale_charset ();
 
-  /* Read input file and convert.  */
-  result = iconv_msgdomain_list (read_po_file (input_file), to_code,
-                                input_file);
+  /* Read input file.  */
+  result = read_po_file (input_file);
+
+  /* Convert if and only if the output syntax supports different encodings.  */
+  if (output_syntax != syntax_properties)
+    result = iconv_msgdomain_list (result, to_code, input_file);
 
   /* Sort the results.  */
   if (sort_by_filepos)
@@ -285,6 +301,11 @@ Conversion target:\n"));
 The default encoding is the current locale's encoding.\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -e, --no-escape             do not use C escapes in output (default)\n"));
@@ -301,6 +322,8 @@ Output details:\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 8e5a0174b26dd8b5d20c7906645f6bf3950351d3..960a812113deb2376f9abfea96ad24c531b38182 100644 (file)
@@ -58,6 +58,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 1 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -104,7 +106,7 @@ main (int argc, char **argv)
   do_version = false;
   output_file = NULL;
 
-  while ((opt = getopt_long (argc, argv, "D:eEFhio:sVw:", long_options, NULL))
+  while ((opt = getopt_long (argc, argv, "D:eEFhio:pPsVw:", long_options, NULL))
         != EOF)
     switch (opt)
       {
@@ -139,6 +141,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -267,6 +277,11 @@ The results are written to standard output if no output file is specified\n\
 or if it is -.\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -e, --no-escape             do not use C escapes in output (default)\n"));
@@ -283,6 +298,8 @@ Output details:\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index e6e24c67dc6b014bbcdb05d0b4dbbf8521f36c82..8e98aa4fc9313b9c31f2aeeb34aa5765527b29cd 100644 (file)
@@ -76,6 +76,7 @@ static const struct option long_options[] =
   { "directory", required_argument, NULL, 'D' },
   { "help", no_argument, NULL, 'h' },
   { "input", required_argument, NULL, 'i' },
+  { "properties-input", no_argument, NULL, 'P' },
   { "version", no_argument, NULL, 'V' },
   { NULL, 0, NULL, 0 }
 };
@@ -120,7 +121,8 @@ 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:hi:V", long_options, NULL)) != EOF)
+  while ((opt = getopt_long (argc, argv, "+D:hi:PV", long_options, NULL))
+        != EOF)
     switch (opt)
       {
       case '\0':               /* Long option.  */
@@ -143,6 +145,10 @@ main (int argc, char **argv)
        input_file = optarg;
        break;
 
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 'V':
        do_version = true;
        break;
@@ -250,6 +256,11 @@ Input file location:\n"));
 If no input file is given or if it is -, standard input is read.\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Informative output:\n"));
       printf (_("\
   -h, --help                  display this help and exit\n"));
index 9ed4097c141089e16a715d2fb55c2ac727018651..aa6f1dc6acd7e3437523db574db8127210c3a062 100644 (file)
@@ -107,6 +107,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 3 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -159,7 +161,8 @@ 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:sVw:", long_options, NULL))
+  while ((opt = getopt_long (argc, argv, "+D:EFhi:o:pPsVw:", long_options,
+                            NULL))
         != EOF)
     switch (opt)
       {
@@ -195,6 +198,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -384,6 +395,11 @@ Useful FILTER-OPTIONs when the FILTER is 'sed':\n"));
   -n, --quiet, --silent       suppress automatic printing of pattern space\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
       --no-escape             do not use C escapes in output (default)\n"));
@@ -402,6 +418,8 @@ Output details:\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 7a1fbe20b47728e74a0d4366b2ba5f3184f3ca96..265331e9854176cffd1786b196fe53f2edf5b82e 100644 (file)
@@ -52,6 +52,7 @@
 #include "message.h"
 #include "open-po.h"
 #include "read-po.h"
+#include "po-charset.h"
 
 #define _(str) gettext (str)
 
@@ -160,6 +161,7 @@ static const struct option long_options[] =
   { "locale", required_argument, NULL, 'l' },
   { "no-hash", no_argument, NULL, CHAR_MAX + 6 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
   { "resource", required_argument, NULL, 'r' },
   { "statistics", no_argument, &do_statistics, 1 },
   { "strict", no_argument, NULL, 'S' },
@@ -191,6 +193,7 @@ main (int argc, char *argv[])
   bool do_help = false;
   bool do_version = false;
   bool strict_uniforum = false;
+  const char *canon_encoding;
   struct msg_domain *domain;
 
   /* Set default value for global variables.  */
@@ -211,7 +214,7 @@ main (int argc, char *argv[])
   bindtextdomain (PACKAGE, relocate (LOCALEDIR));
   textdomain (PACKAGE);
 
-  while ((opt = getopt_long (argc, argv, "a:cCd:D:fhjl:o:r:vV", long_options,
+  while ((opt = getopt_long (argc, argv, "a:cCd:D:fhjl:o:Pr:vV", long_options,
                             NULL))
         != EOF)
     switch (opt)
@@ -258,6 +261,9 @@ main (int argc, char *argv[])
       case 'o':
        output_file_name = optarg;
        break;
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
       case 'r':
        java_resource_name = optarg;
        break;
@@ -417,6 +423,9 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
       ++optind;
     }
 
+  /* We know a priori that properties_parse() converts strings to UTF-8.  */
+  canon_encoding = (input_syntax == syntax_properties ? po_charset_utf8 : NULL);
+
   /* Remove obsolete messages.  They were only needed for duplicate
      checking.  */
   for (domain = domain_list; domain != NULL; domain = domain->next)
@@ -432,14 +441,14 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
     {
       if (java_mode)
        {
-         if (msgdomain_write_java (domain->mlp, java_resource_name,
-                                   java_locale_name, java_class_directory,
-                                   assume_java2))
+         if (msgdomain_write_java (domain->mlp, canon_encoding,
+                                   java_resource_name, java_locale_name,
+                                   java_class_directory, assume_java2))
            exit_status = EXIT_FAILURE;
        }
       else if (tcl_mode)
        {
-         if (msgdomain_write_tcl (domain->mlp,
+         if (msgdomain_write_tcl (domain->mlp, canon_encoding,
                                   tcl_locale_name, tcl_base_directory))
            exit_status = EXIT_FAILURE;
        }
@@ -554,6 +563,11 @@ The -l and -d options are mandatory.  The .msg file is written in the\n\
 specified directory.\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input files are in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Input file interpretation:\n"));
       printf (_("\
   -c, --check                 perform all the checks implied by\n\
@@ -1402,7 +1416,7 @@ msgfmt_add_message (default_po_reader_ty *this,
                    char *msgid_plural,
                    char *msgstr, size_t msgstr_len,
                    lex_pos_ty *msgstr_pos,
-                   bool obsolete)
+                   bool force_fuzzy, bool obsolete)
 {
   /* Check whether already a domain is specified.  If not, use default
      domain.  */
@@ -1417,7 +1431,7 @@ msgfmt_add_message (default_po_reader_ty *this,
 
   /* Invoke superclass method.  */
   default_add_message (this, msgid, msgid_pos, msgid_plural,
-                      msgstr, msgstr_len, msgstr_pos, obsolete);
+                      msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
 }
 
 
@@ -1558,7 +1572,8 @@ read_po_file_msgfmt (char *filename)
       pop->mlp = current_domain->mlp;
     }
   po_lex_pass_obsolete_entries (true);
-  po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, filename);
+  po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, filename,
+          input_syntax);
   po_reader_free ((abstract_po_reader_ty *) pop);
 
   if (fp != stdin)
index b4181debc8eea4ee2163efe06aa14ae331616706..fba6e74147a52a4b356e609b7637597f3394552a 100644 (file)
@@ -97,6 +97,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 6 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "regexp", required_argument, NULL, 'e' },
   { "sort-by-file", no_argument, NULL, CHAR_MAX + 4 },
   { "sort-output", no_argument, NULL, CHAR_MAX + 5 },
@@ -159,7 +161,7 @@ main (int argc, char **argv)
   grep_args[1] = string_list_alloc ();
   grep_args[2] = string_list_alloc ();
 
-  while ((opt = getopt_long (argc, argv, "CD:e:Ef:FhiKM:N:o:TVw:",
+  while ((opt = getopt_long (argc, argv, "CD:e:Ef:FhiKM:N:o:pPTVw:",
                             long_options, NULL))
         != EOF)
     switch (opt)
@@ -227,6 +229,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 'S':
        message_print_style_uniforum ();
        break;
@@ -468,6 +478,11 @@ expressions if -E is given, or fixed strings if -F is given.\n\
 "));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
       --no-escape             do not use C escapes in output (default)\n"));
@@ -484,6 +499,8 @@ Output details:\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 6abb690f77a255e7b7b3d5a056148c8574a37649..2205dddc6f7e95d74fdcc8f5d152ad66b9767ab3 100644 (file)
@@ -124,6 +124,8 @@ static const struct option long_options[] =
   { "no-translator", no_argument, NULL, CHAR_MAX + 1 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "version", no_argument, NULL, 'V' },
   { "width", required_argument, NULL, 'w' },
   { NULL, 0, NULL, 0 }
@@ -172,7 +174,7 @@ main (int argc, char **argv)
   input_file = NULL;
   locale = NULL;
 
-  while ((opt = getopt_long (argc, argv, "hi:l:o:Vw:", long_options, NULL))
+  while ((opt = getopt_long (argc, argv, "hi:l:o:pPVw:", long_options, NULL))
         != EOF)
     switch (opt)
       {
@@ -200,6 +202,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 'V':
        do_version = true;
        break;
@@ -356,12 +366,19 @@ If no output file is given, it depends on the --locale option or the user's\n\
 locale setting.  If it is -, the results are written to standard output.\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -l, --locale=LL_CC          set target locale\n"));
       printf (_("\
       --no-translator         assume the PO file is automatically generated\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 1074479a796c3c1266a015ca209ded4e77bc61b4..bfb83a4115d1e51930ae90a8e1a8001d31d50314 100644 (file)
@@ -191,6 +191,8 @@ two different charsets \"%s\" and \"%s\" in input file"),
                {
                  if (is_ascii_message_list (mlp))
                    canon_from_code = po_charset_ascii;
+                 else if (mdlp->encoding != NULL)
+                   canon_from_code = mdlp->encoding;
                  else
                    {
                      if (k == 0)
@@ -352,6 +354,22 @@ domain \"%s\" in input file `%s' doesn't contain a header entry with a charset s
       message_list_remove_if_not (mlp, is_message_selected);
     }
 
+  /* Determine the common known a-priori encoding, if any.  */
+  if (nfiles > 0)
+    {
+      bool all_same_encoding = true;
+
+      for (n = 1; n < nfiles; n++)
+       if (mdlps[n]->encoding != mdlps[0]->encoding)
+         {
+           all_same_encoding = false;
+           break;
+         }
+
+      if (all_same_encoding)
+       total_mdlp->encoding = mdlps[0]->encoding;
+    }
+
   /* Determine the target encoding for the remaining messages.  */
   if (to_code != NULL)
     {
@@ -421,7 +439,7 @@ Input files contain messages in different encodings, %s and %s among others.\n\
 Converting the output to UTF-8.\n\
 To select a different output encoding, use the --to-code option.\n\
 "), first, second));
-         canon_to_code = po_charset_canonicalize ("UTF-8");
+         canon_to_code = po_charset_utf8;
        }
       else if (first != NULL && with_ASCII && all_ASCII_compatible)
        {
index 21faaf48aebf33ca907bf81519bc7f5694bcdf50..1bebd615733f7e1b5d06a05d68700761b9127e5f 100644 (file)
@@ -391,8 +391,9 @@ iconv_msgdomain_list (msgdomain_list_ty *mdlp,
           to_code);
 
   for (k = 0; k < mdlp->nitems; k++)
-    iconv_message_list (mdlp->item[k]->messages, NULL, canon_to_code,
+    iconv_message_list (mdlp->item[k]->messages, mdlp->encoding, canon_to_code,
                        from_filename);
 
+  mdlp->encoding = canon_to_code;
   return mdlp;
 }
index 96a4bd9f0dcd9f8c4f16daeb5ed863423158af92..009b50a056c1c7d9d6da79320d7c4f08737db3cc 100644 (file)
@@ -94,6 +94,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 4 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "quiet", no_argument, NULL, 'q' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
@@ -161,8 +163,8 @@ main (int argc, char **argv)
   do_version = false;
   output_file = NULL;
 
-  while ((opt
-         = getopt_long (argc, argv, "C:D:eEFhimo:qsUvVw:", long_options, NULL))
+  while ((opt = getopt_long (argc, argv, "C:D:eEFhimo:pPqsUvVw:", long_options,
+                            NULL))
         != EOF)
     switch (opt)
       {
@@ -209,6 +211,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 'q':
        quiet = true;
        break;
@@ -323,6 +333,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
           "--sort-output", "--sort-by-file");
 
+  /* In update mode, --properties-input implies --properties-output.  */
+  if (update_mode && input_syntax == syntax_properties)
+    message_print_syntax_properties ();
+
   /* Merge the two files.  */
   result = merge (argv[optind], argv[optind + 1], &def);
 
@@ -460,6 +474,11 @@ Operation modifiers:\n"));
   -N, --no-fuzzy-matching     do not use fuzzy matching\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input files are in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -e, --no-escape             do not use C escapes in output (default)\n"));
@@ -476,6 +495,8 @@ Output details:\n"));
       printf (_("\
       --strict                strict Uniforum output style\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
@@ -1163,6 +1184,10 @@ merge (const char *fn1, const char *fn2, msgdomain_list_ty **defp)
        }
     }
 
+  /* Determine the known a-priori encoding, if any.  */
+  if (def->encoding == ref->encoding)
+    result->encoding = def->encoding;
+
   /* Report some statistics.  */
   if (verbosity_level > 0)
     fprintf (stderr, _("%s\
index 66176b5f36b8c23b77b2aeb055ba8350fec4e49b..e3126e4c69441c2fb06ea820ea9f1b9f43889995 100644 (file)
@@ -71,6 +71,7 @@ static const struct option long_options[] =
   { "no-escape", no_argument, NULL, 'e' },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "resource", required_argument, NULL, 'r' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -113,7 +114,7 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, relocate (LOCALEDIR));
   textdomain (PACKAGE);
 
-  while ((optchar = getopt_long (argc, argv, "d:eEhijl:o:r:svVw:",
+  while ((optchar = getopt_long (argc, argv, "d:eEhijl:o:pr:svVw:",
                                 long_options, NULL))
         != EOF)
     switch (optchar)
@@ -155,6 +156,10 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
       case 'r':
        java_resource_name = optarg;
        break;
@@ -383,6 +388,8 @@ Output details:\n"));
       printf (_("\
       --strict                write strict uniforum style\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 31a2ba42434b7de032b31dd76cfcae117752ca66..5222534327e7a6e499fac5569fadae76541151fa 100644 (file)
@@ -62,6 +62,8 @@ static const struct option long_options[] =
   { "no-location", no_argument, &line_comment, 0 },
   { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
   { "output-file", required_argument, NULL, 'o' },
+  { "properties-input", no_argument, NULL, 'P' },
+  { "properties-output", no_argument, NULL, 'p' },
   { "repeated", no_argument, NULL, 'd' },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
@@ -118,7 +120,7 @@ main (int argc, char **argv)
   less_than = INT_MAX;
   use_first = false;
 
-  while ((optchar = getopt_long (argc, argv, "dD:eEFhino:st:uVw:",
+  while ((optchar = getopt_long (argc, argv, "dD:eEFhino:pPst:uVw:",
                                 long_options, NULL)) != EOF)
     switch (optchar)
       {
@@ -162,6 +164,14 @@ main (int argc, char **argv)
        output_file = optarg;
        break;
 
+      case 'p':
+       message_print_syntax_properties ();
+       break;
+
+      case 'P':
+       input_syntax = syntax_properties;
+       break;
+
       case 's':
        sort_by_msgid = true;
        break;
@@ -320,6 +330,11 @@ Message selection:\n"));
   -u, --unique                print only unique messages, discard duplicates\n"));
       printf ("\n");
       printf (_("\
+Input file syntax:\n"));
+      printf (_("\
+  -P, --properties-input      input file is in Java .properties syntax\n"));
+      printf ("\n");
+      printf (_("\
 Output details:\n"));
       printf (_("\
   -t, --to-code=NAME          encoding for output\n"));
@@ -341,6 +356,8 @@ Output details:\n"));
       printf (_("\
       --strict                write out strict Uniforum conforming .po file\n"));
       printf (_("\
+  -p, --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
index 355ffba67b4aa5ff80e1437c40d1a9c40172d9c0..e8386bb116840d68dff48a6c690cac34f7619d80 100644 (file)
 /* Specification.  */
 #include "po-gram.h"
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "str-list.h"
 #include "po-lex.h"
+#include "po-charset.h"
 #include "error.h"
 #include "xmalloc.h"
 #include "gettext.h"
@@ -91,6 +93,20 @@ static long plural_counter;
   if ((value1).obsolete != (value2).obsolete) \
     po_gram_error_at_line (&(value2).pos, _("inconsistent use of #~"));
 
+static inline void
+do_callback_message (char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
+                    char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
+                    bool obsolete)
+{
+  /* Test for header entry.  Ignore fuzziness of the header entry.  */
+  if (msgid[0] == '\0' && !obsolete)
+    po_lex_charset_set (msgstr, gram_pos.file_name);
+
+  po_callback_message (msgid, msgid_pos, msgid_plural,
+                      msgstr, msgstr_len, msgstr_pos,
+                      false, obsolete);
+}
+
 %}
 
 %token COMMENT
@@ -148,7 +164,7 @@ message
                  check_obsolete ($1, $3);
                  check_obsolete ($1, $4);
                  if (!$1.obsolete || pass_obsolete_entries)
-                   po_callback_message (string2, &$1.pos, NULL,
+                   do_callback_message (string2, &$1.pos, NULL,
                                         string4, strlen (string4) + 1, &$3.pos,
                                         $1.obsolete);
                  else
@@ -165,7 +181,7 @@ message
                  check_obsolete ($1, $3);
                  check_obsolete ($1, $4);
                  if (!$1.obsolete || pass_obsolete_entries)
-                   po_callback_message (string2, &$1.pos, $3.string,
+                   do_callback_message (string2, &$1.pos, $3.string,
                                         $4.rhs.msgstr, $4.rhs.msgstr_len, &$4.pos,
                                         $1.obsolete);
                  else
index d3aaf324c2c30a27d6ceff709481a436dcf65f63..d5be021b3cf9972098b60958e4193ae56f8c54df 100644 (file)
@@ -618,18 +618,11 @@ lex_start (FILE *fp, const char *real_filename, const char *logical_filename)
 void
 lex_end ()
 {
-  if (error_message_count > 0)
-    error (EXIT_FAILURE, 0,
-          ngettext ("found %d fatal error", "found %d fatal errors",
-                    error_message_count),
-          error_message_count);
-
   mbf->fp = NULL;
   gram_pos.file_name = NULL;
   gram_pos.line_number = 0;
   gram_pos_column = 0;
   signal_eilseq = false;
-  error_message_count = 0;
   po_lex_obsolete = false;
   po_lex_charset_close ();
 }
index 4805fd75ff4a6cbbdc097f73aef2f03c8fb8dddb..bc562eae26cc5218dd20604a52e7b641edcd5621 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#include "po-charset.h"
 #include "po-gram.h"
 #include "po-hash.h"
+#include "read-properties.h"
 #include "xmalloc.h"
+#include "gettext.h"
 
 /* Local variables.  */
 static abstract_po_reader_ty *callback_arg;
@@ -95,11 +96,12 @@ call_directive_message (abstract_po_reader_ty *pop,
                        char *msgid_plural,
                        char *msgstr, size_t msgstr_len,
                        lex_pos_ty *msgstr_pos,
-                       bool obsolete)
+                       bool force_fuzzy, bool obsolete)
 {
   if (pop->methods->directive_message)
     pop->methods->directive_message (pop, msgid, msgid_pos, msgid_plural,
-                                    msgstr, msgstr_len, msgstr_pos, obsolete);
+                                    msgstr, msgstr_len, msgstr_pos,
+                                    force_fuzzy, obsolete);
 }
 
 static inline void
@@ -135,7 +137,7 @@ call_comment_special (abstract_po_reader_ty *pop, const char *s)
 /* Exported functions.  */
 
 
-void
+static inline void
 po_scan_start (abstract_po_reader_ty *pop)
 {
   /* The parse will call the po_callback_... functions (see below)
@@ -147,7 +149,7 @@ po_scan_start (abstract_po_reader_ty *pop)
   call_parse_brief (pop);
 }
 
-void
+static inline void
 po_scan_end (abstract_po_reader_ty *pop)
 {
   call_parse_debrief (pop);
@@ -157,14 +159,34 @@ po_scan_end (abstract_po_reader_ty *pop)
 
 void
 po_scan (abstract_po_reader_ty *pop, FILE *fp,
-        const char *real_filename, const char *logical_filename)
+        const char *real_filename, const char *logical_filename,
+        input_syntax_ty syntax)
 {
   /* Parse the stream's content.  */
-  lex_start (fp, real_filename, logical_filename);
-  po_scan_start (pop);
-  po_gram_parse ();
-  po_scan_end (pop);
-  lex_end ();
+  switch (syntax)
+    {
+    case syntax_po:
+      lex_start (fp, real_filename, logical_filename);
+      po_scan_start (pop);
+      po_gram_parse ();
+      po_scan_end (pop);
+      lex_end ();
+      break;
+    case syntax_properties:
+      po_scan_start (pop);
+      properties_parse (pop, fp, real_filename, logical_filename);
+      po_scan_end (pop);
+      break;
+    default:
+      abort ();
+    }
+
+  if (error_message_count > 0)
+    error (EXIT_FAILURE, 0,
+          ngettext ("found %d fatal error", "found %d fatal errors",
+                    error_message_count),
+          error_message_count);
+  error_message_count = 0;
 }
 
 
@@ -188,16 +210,12 @@ po_callback_domain (char *name)
 void
 po_callback_message (char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
                     char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
-                    bool obsolete)
+                    bool force_fuzzy, bool obsolete)
 {
   /* assert(callback_arg); */
-
-  /* Test for header entry.  Ignore fuzziness of the header entry.  */
-  if (msgid[0] == '\0' && !obsolete)
-    po_lex_charset_set (msgstr, gram_pos.file_name);
-
   call_directive_message (callback_arg, msgid, msgid_pos, msgid_plural,
-                         msgstr, msgstr_len, msgstr_pos, obsolete);
+                         msgstr, msgstr_len, msgstr_pos,
+                         force_fuzzy, obsolete);
 }
 
 
index 87590a67298ca5fd88de1d3b13bc5008fa06d676..4140fc87349660c6aa4c60ee62c09ca34b50b88d 100644 (file)
@@ -73,7 +73,7 @@ struct abstract_po_reader_class_ty
                             char *msgid_plural,
                             char *msgstr, size_t msgstr_len,
                             lex_pos_ty *msgstr_pos,
-                            bool obsolete);
+                            bool force_fuzzy, bool obsolete);
 
   /* What to do with a plain-vanilla comment - the expectation is that
      they will be accumulated, and added to the next message
@@ -123,19 +123,20 @@ struct abstract_po_reader_ty
 extern abstract_po_reader_ty *
        po_reader_alloc (abstract_po_reader_class_ty *method_table);
 
-/* Prepare for use of abstract_po_reader_class_ty methods.  */
-extern void
-       po_scan_start (abstract_po_reader_ty *pop);
-
-/* Terminate the use of abstract_po_reader_class_ty methods.  */
-extern void
-       po_scan_end (abstract_po_reader_ty *pop);
+/* Kinds of PO file input syntaxes.  */
+enum input_syntax_ty
+{
+  syntax_po,
+  syntax_properties
+};
+typedef enum input_syntax_ty input_syntax_ty;
 
 /* Read a PO file from a stream, and dispatch to the various
    abstract_po_reader_class_ty methods.  */
 extern void
        po_scan (abstract_po_reader_ty *pop, FILE *fp,
-               const char *real_filename, const char *logical_filename);
+               const char *real_filename, const char *logical_filename,
+               input_syntax_ty syntax);
 
 /* Call the destructor and deallocate a abstract_po_reader_ty (or derived
    class) instance.  */
@@ -150,7 +151,7 @@ extern void po_callback_message (char *msgid, lex_pos_ty *msgid_pos,
                                 char *msgid_plural,
                                 char *msgstr, size_t msgstr_len,
                                 lex_pos_ty *msgstr_pos,
-                                bool obsolete);
+                                bool force_fuzzy, bool obsolete);
 extern void po_callback_comment (const char *s);
 extern void po_callback_comment_dot (const char *s);
 extern void po_callback_comment_filepos (const char *s, size_t line);
index e4aec2089ada749dd0a98157f541021bda99bec7..a31c55ad80abf9025263d8f5a466695e13dd8b6c 100644 (file)
@@ -28,6 +28,7 @@
 #include <string.h>
 
 #include "open-po.h"
+#include "po-charset.h"
 #include "xmalloc.h"
 #include "gettext.h"
 
@@ -51,14 +52,15 @@ static inline void
 call_add_message (struct default_po_reader_ty *this,
                  char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
                  char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
-                 bool obsolete)
+                 bool force_fuzzy, bool obsolete)
 {
   default_po_reader_class_ty *methods =
     (default_po_reader_class_ty *) this->methods;
 
   if (methods->add_message)
     methods->add_message (this, msgid, msgid_pos, msgid_plural,
-                         msgstr, msgstr_len, msgstr_pos, obsolete);
+                         msgstr, msgstr_len, msgstr_pos,
+                         force_fuzzy, obsolete);
 }
 
 static inline void
@@ -230,12 +232,12 @@ default_directive_message (abstract_po_reader_ty *that,
                           char *msgid_plural,
                           char *msgstr, size_t msgstr_len,
                           lex_pos_ty *msgstr_pos,
-                          bool obsolete)
+                          bool force_fuzzy, bool obsolete)
 {
   default_po_reader_ty *this = (default_po_reader_ty *) that;
 
   call_add_message (this, msgid, msgid_pos, msgid_plural,
-                   msgstr, msgstr_len, msgstr_pos, obsolete);
+                   msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
 
   /* Prepare for next message.  */
   default_reset_comment_state (this);
@@ -327,7 +329,7 @@ default_add_message (default_po_reader_ty *this,
                     char *msgid_plural,
                     char *msgstr, size_t msgstr_len,
                     lex_pos_ty *msgstr_pos,
-                    bool obsolete)
+                    bool force_fuzzy, bool obsolete)
 {
   message_ty *mp;
 
@@ -373,6 +375,8 @@ default_add_message (default_po_reader_ty *this,
       mp = message_alloc (msgid, msgid_plural, msgstr, msgstr_len, msgstr_pos);
       mp->obsolete = obsolete;
       default_copy_comment_state (this, mp);
+      if (force_fuzzy)
+       mp->is_fuzzy = true;
 
       call_frob_new_message (this, mp, msgid_pos, msgstr_pos);
 
@@ -428,6 +432,9 @@ int line_comment = 1;
    appropriately.  Defaults to false.  */
 bool allow_duplicates = false;
 
+/* Expected syntax of the input files.  */
+input_syntax_ty input_syntax = syntax_po;
+
 
 msgdomain_list_ty *
 read_po (FILE *fp, const char *real_filename, const char *logical_filename)
@@ -443,8 +450,12 @@ read_po (FILE *fp, const char *real_filename, const char *logical_filename)
   pop->allow_duplicates_if_same_msgstr = false;
   pop->mdlp = msgdomain_list_alloc (!pop->allow_duplicates);
   pop->mlp = msgdomain_list_sublist (pop->mdlp, pop->domain, true);
+  if (input_syntax == syntax_properties)
+    /* We know a priori that properties_parse() converts strings to UTF-8.  */
+    pop->mdlp->encoding = po_charset_utf8;
   po_lex_pass_obsolete_entries (true);
-  po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename);
+  po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename,
+          input_syntax);
   mdlp = pop->mdlp;
   po_reader_free ((abstract_po_reader_ty *) pop);
   return mdlp;
index f2f6807f70da493c5f3a105758c1e2c8539a274a..ce5c3e366abbe83d16c51217954192405b0ab406 100644 (file)
@@ -47,7 +47,7 @@ struct default_po_reader_class_ty
   void (*add_message) (struct default_po_reader_ty *pop,
                       char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
                       char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
-                      bool obsolete);
+                      bool force_fuzzy, bool obsolete);
 
   /* How to modify a new message before adding it to the list.  */
   void (*frob_new_message) (struct default_po_reader_ty *pop, message_ty *mp,
@@ -116,7 +116,7 @@ extern void default_directive_message (abstract_po_reader_ty *that,
                                       char *msgid_plural,
                                       char *msgstr, size_t msgstr_len,
                                       lex_pos_ty *msgstr_pos,
-                                      bool obsolete);
+                                      bool force_fuzzy, bool obsolete);
 extern void default_comment (abstract_po_reader_ty *that, const char *s);
 extern void default_comment_dot (abstract_po_reader_ty *that, const char *s);
 extern void default_comment_filepos (abstract_po_reader_ty *that,
@@ -130,7 +130,7 @@ extern void default_add_message (default_po_reader_ty *this,
                                 char *msgid_plural,
                                 char *msgstr, size_t msgstr_len,
                                 lex_pos_ty *msgstr_pos,
-                                bool obsolete);
+                                bool force_fuzzy, bool obsolete);
 
 /* Allocate a fresh default_po_reader_ty (or derived class) instance and
    call its constructor.  */
@@ -147,6 +147,9 @@ extern int line_comment;
    appropriately.  Defaults to false.  */
 extern bool allow_duplicates;
 
+/* Expected syntax of the input files.  */
+extern input_syntax_ty input_syntax;
+
 /* Read the input file from a stream.  Returns a list of messages.  */
 extern msgdomain_list_ty *read_po (FILE *fp, const char *real_filename,
                                   const char *logical_filename);
diff --git a/gettext-tools/src/read-properties.c b/gettext-tools/src/read-properties.c
new file mode 100644 (file)
index 0000000..2faa300
--- /dev/null
@@ -0,0 +1,543 @@
+/* Reading Java .properties files.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include "read-properties.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "error.h"
+#include "progname.h"
+#include "message.h"
+#include "read-po-abstract.h"
+#include "xmalloc.h"
+#include "exit.h"
+#include "msgl-ascii.h"
+#include "utf16-ucs4.h"
+#include "ucs4-utf8.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+/* The format of the Java .properties files is documented in the JDK
+   documentation for class java.util.Properties.  In the case of .properties
+   files for PropertyResourceBundle, each non-comment line contains a
+   key/value pair in the form "key = value" or "key : value" or "key value",
+   where the key is the msgid and the value is the msgstr.  Messages with
+   plurals are not supported in this format.  */
+
+/* Handling of comments: We copy all comments from the .properties file to
+   the PO file. This is not really needed; it's a service for translators
+   who don't like PO files and prefer to maintain the .properties file.  */
+
+/* Real filename, used in error messages about the input file.  */
+static const char *real_file_name;
+
+/* File name and line number.  */
+extern lex_pos_ty gram_pos;
+
+/* The input file stream.  */
+static FILE *fp;
+
+
+/* Phase 1: Read an ISO-8859-1 character.
+   Max. 1 pushback character.  */
+
+static int
+phase1_getc ()
+{
+  int c;
+
+  c = getc (fp);
+
+  if (c == EOF)
+    {
+      if (ferror (fp))
+       error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
+              real_file_name);
+      return EOF;
+    }
+
+  return c;
+}
+
+static inline void
+phase1_ungetc (int c)
+{
+  if (c != EOF)
+    ungetc (c, fp);
+}
+
+
+/* Phase 2: Read an ISO-8859-1 character, treating CR/LF like a single LF.
+   Max. 2 pushback characters.  */
+
+static unsigned char phase2_pushback[2];
+static int phase2_pushback_length;
+
+static int
+phase2_getc ()
+{
+  int c;
+
+  if (phase2_pushback_length)
+    c = phase2_pushback[--phase2_pushback_length];
+  else
+    {
+      c = phase1_getc ();
+
+      if (c == '\r')
+       {
+         int c2 = phase1_getc ();
+         if (c2 == '\n')
+           c = c2;
+         else
+           phase1_ungetc (c2);
+       }
+    }
+
+  if (c == '\n')
+    gram_pos.line_number++;
+
+  return c;
+}
+
+static void
+phase2_ungetc (int c)
+{
+  if (c == '\n')
+    --gram_pos.line_number;
+  if (c != EOF)
+    phase2_pushback[phase2_pushback_length++] = c;
+}
+
+
+/* Phase 3: Read an ISO-8859-1 character, treating CR/LF like a single LF,
+   with handling of continuation lines.
+   Max. 1 pushback character.  */
+
+static int
+phase3_getc ()
+{
+  int c = phase2_getc ();
+
+  for (;;)
+    {
+      if (c != '\\')
+       return c;
+
+      c = phase2_getc ();
+      if (c != '\n')
+       {
+         phase2_ungetc (c);
+         return '\\';
+       }
+
+      /* Skip the backslash-newline and all whitespace that follows it.  */
+      do
+       c = phase2_getc ();
+      while (c == ' ' || c == '\t' || c == '\r' || c == '\f');
+    }
+}
+
+static inline void
+phase3_ungetc (int c)
+{
+  phase2_ungetc (c);
+}
+
+
+/* Phase 4: Read an UTF-16 codepoint, treating CR/LF like a single LF,
+   with handling of continuation lines and of \uxxxx sequences.  */
+
+static int
+phase4_getuc ()
+{
+  int c = phase3_getc ();
+
+  if (c == EOF)
+    return -1;
+  if (c == '\\')
+    {
+      int c2 = phase3_getc ();
+
+      if (c2 == 't')
+       return '\t';
+      if (c2 == 'n')
+       return '\n';
+      if (c2 == 'r')
+       return '\r';
+      if (c2 == 'f')
+       return '\f';
+      if (c2 == 'u')
+       {
+         unsigned int n = 0;
+         int i;
+
+         for (i = 0; i < 4; i++)
+           {
+             int c1 = phase3_getc ();
+
+             if (c1 >= '0' && c1 <= '9')
+               n = (n << 4) + (c1 - '0');
+             else if (c1 >= 'A' && c1 <= 'F')
+               n = (n << 4) + (c1 - 'A' + 10);
+             else if (c1 >= 'a' && c1 <= 'f')
+               n = (n << 4) + (c1 - 'a' + 10);
+             else
+               {
+                 phase3_ungetc (c1);
+                 error_with_progname = false;
+                 error (0, 0, _("%s:%d: warning: invalid \\uxxxx syntax for Unicode character"),
+                        real_file_name, gram_pos.line_number);
+                 error_with_progname = true;
+                 return 'u';
+               }
+           }
+         return n;
+       }
+
+      return c2;
+    }
+  else
+    return c;
+}
+
+
+/* Converts a string from ISO-8859-1 encoding to UTF-8 encoding.  */
+static char *
+conv_from_iso_8859_1 (char *string)
+{
+  if (is_ascii_string (string))
+    return string;
+  else
+    {
+      size_t length = strlen (string);
+      /* Each ISO-8859-1 character needs 2 bytes at worst.  */
+      unsigned char *utf8_string = (unsigned char *) xmalloc (2 * length + 1);
+      unsigned char *q = utf8_string;
+      const char *str = string;
+      const char *str_limit = str + length;
+
+      while (str < str_limit)
+       {
+         unsigned int uc = (unsigned char) *str++;
+         int n = u8_uctomb (q, uc, 6);
+         assert (n > 0);
+         q += n;
+       }
+      *q = '\0';
+      assert (q - utf8_string <= 2 * length);
+
+      return (char *) utf8_string;
+    }
+}
+
+
+/* Converts a string from JAVA encoding (with \uxxxx sequences) to UTF-8
+   encoding.  May destructively modify the argument string.  */
+static char *
+conv_from_java (char *string)
+{
+  /* This conversion can only shrink the string, never increase its size.
+     So there is no need to xmalloc the result freshly.  */
+  const char *p = string;
+  char *q = string;
+
+  while (*p != '\0')
+    {
+      if (p[0] == '\\' && p[1] == 'u')
+       {
+         unsigned int n = 0;
+         int i;
+
+         for (i = 0; i < 4; i++)
+           {
+             int c1 = (unsigned char) p[2 + i];
+
+             if (c1 >= '0' && c1 <= '9')
+               n = (n << 4) + (c1 - '0');
+             else if (c1 >= 'A' && c1 <= 'F')
+               n = (n << 4) + (c1 - 'A' + 10);
+             else if (c1 >= 'a' && c1 <= 'f')
+               n = (n << 4) + (c1 - 'a' + 10);
+             else
+               goto just_one_byte;
+           }
+
+         if (i == 4)
+           {
+             unsigned int uc;
+
+             if (n >= 0xd800 && n < 0xdc00)
+               {
+                 if (p[6] == '\\' && p[7] == 'u')
+                   {
+                     unsigned int m = 0;
+
+                     for (i = 0; i < 4; i++)
+                       {
+                         int c1 = (unsigned char) p[8 + i];
+
+                         if (c1 >= '0' && c1 <= '9')
+                           m = (m << 4) + (c1 - '0');
+                         else if (c1 >= 'A' && c1 <= 'F')
+                           m = (m << 4) + (c1 - 'A' + 10);
+                         else if (c1 >= 'a' && c1 <= 'f')
+                           m = (m << 4) + (c1 - 'a' + 10);
+                         else
+                           goto just_one_byte;
+                       }
+
+                     if (i == 4 && (m >= 0xdc00 && m < 0xe000))
+                       {
+                         /* Combine two UTF-16 words to a character.  */
+                         uc = 0x10000 + ((n - 0xd800) << 10) + (m - 0xdc00);
+                         p += 12;
+                       }
+                     else
+                       goto just_one_byte;
+                   }
+                 else
+                   goto just_one_byte;
+               }
+             else
+               {
+                 uc = n;
+                 p += 6;
+               }
+
+             q += u8_uctomb (q, uc, 6);
+             continue;
+           }
+       }
+      just_one_byte:
+       *q++ = *p++;
+    }
+  *q = '\0';
+  return string;
+}
+
+
+/* Reads a key or value string.
+   Returns the string in UTF-8 encoding, or NULL if the end of the logical
+   line is reached.
+   Parsing ends:
+     - when returning NULL, after the end of the logical line,
+     - otherwise, if in_key is true, after the whitespace and possibly the
+       separator that follows after the string,
+     - otherwise, if in_key is false, after the end of the logical line. */
+
+static char *
+read_escaped_string (bool in_key)
+{
+  static unsigned short *buffer; 
+  static size_t bufmax;
+  static size_t buflen;
+  int c;
+
+  /* Skip whitespace before the string.  */
+  do
+    c = phase3_getc ();
+  while (c == ' ' || c == '\t' || c == '\r' || c == '\f');
+
+  if (c == EOF || c == '\n')
+    /* Empty string.  */
+    return NULL;
+
+  /* Start accumulating the string.  We store the string in UTF-16 before
+     converting it to UTF-8.  Why not converting every character directly to
+     UTF-8? Because a string can contain surrogates like \uD800\uDF00, and
+     we must combine them to a single UTF-8 character.  */
+  buflen = 0;
+  for (;;)
+    {
+      if (in_key && (c == '=' || c == ':'
+                    || c == ' ' || c == '\t' || c == '\r' || c == '\f'))
+       {
+         /* Skip whitespace after the string.  */
+         while (c == ' ' || c == '\t' || c == '\r' || c == '\f')
+           c = phase3_getc ();
+         /* Skip '=' or ':' separator.  */
+         if (!(c == '=' || c == ':'))
+           phase3_ungetc (c);
+         break;
+       }
+
+      phase3_ungetc (c);
+
+      /* Read the next UTF-16 codepoint.  */
+      c = phase4_getuc ();
+      if (c < 0)
+       break;
+      /* Append it to the buffer.  */
+      if (buflen >= bufmax)
+       {
+         bufmax += 100;
+         buffer = xrealloc (buffer, bufmax * sizeof (unsigned short));
+       }
+      buffer[buflen++] = c;
+
+      c = phase3_getc ();
+      if (c == EOF || c == '\n')
+       {
+         if (in_key)
+           phase3_ungetc (c);
+         break;
+       }
+    }
+
+  /* Now convert from UTF-16 to UTF-8.  */
+  {
+    size_t pos;
+    unsigned char *utf8_string;
+    unsigned char *q;
+
+    /* Each UTF-16 word needs 3 bytes at worst.  */
+    utf8_string = (unsigned char *) xmalloc (3 * buflen + 1);
+    for (pos = 0, q = utf8_string; pos < buflen; )
+      {
+       unsigned int uc;
+       int n;
+
+       pos += u16_mbtouc (&uc, buffer + pos, buflen - pos);
+       n = u8_uctomb (q, uc, 6);
+       assert (n > 0);
+       q += n;
+      }
+    *q = '\0';
+    assert (q - utf8_string <= 3 * buflen);
+
+    return (char *) utf8_string;
+  }
+}
+
+
+/* Read a .properties file from a stream, and dispatch to the various
+   abstract_po_reader_class_ty methods.  */
+void
+properties_parse (abstract_po_reader_ty *this, FILE *file,
+                 const char *real_filename, const char *logical_filename)
+{
+  fp = file;
+  real_file_name = real_filename;
+  gram_pos.file_name = xstrdup (real_file_name);
+  gram_pos.line_number = 1;
+
+  for (;;)
+    {
+      int c;
+      bool comment;
+      bool hidden;
+
+      c = phase2_getc ();
+
+      if (c == EOF)
+       break;
+
+      comment = false;
+      hidden = false;
+      if (c == '#')
+       comment = true;
+      else if (c == '!')
+       {
+         /* For compatibility with write-properties.c, we treat '!' not
+            followed by space as a fuzzy or untranslated message.  */
+         int c2 = phase2_getc ();
+         if (c2 == ' ' || c2 == '\n' || c2 == EOF)
+           comment = true;
+         else
+           hidden = true;
+         phase2_ungetc (c2);
+       }
+      else
+       phase2_ungetc (c);
+
+      if (comment)
+       {
+         /* A comment line.  */
+         static char *buffer;
+         static size_t bufmax;
+         static size_t buflen;
+
+         buflen = 0;
+         for (;;)
+           {
+             c = phase2_getc ();
+
+             if (buflen >= bufmax)
+               {
+                 bufmax += 100;
+                 buffer = xrealloc (buffer, bufmax);
+               }
+
+             if (c == EOF || c == '\n')
+               break;
+
+             buffer[buflen++] = c;
+           }
+         buffer[buflen] = '\0';
+
+         po_callback_comment (conv_from_java (conv_from_iso_8859_1 (buffer)));
+       }
+      else
+       {
+         /* A key/value pair.  */
+         char *msgid;
+         lex_pos_ty msgid_pos;
+
+         msgid_pos = gram_pos;
+         msgid = read_escaped_string (true);
+         if (msgid == NULL)
+           /* Skip blank line.  */
+           ;
+         else
+           {
+             char *msgstr;
+             lex_pos_ty msgstr_pos;
+             bool force_fuzzy;
+
+             msgstr_pos = gram_pos;
+             msgstr = read_escaped_string (false);
+             if (msgstr == NULL)
+               msgstr = xstrdup ("");
+
+             /* Be sure to make the message fuzzy if it was commented out
+                and if it is not already header/fuzzy/untranslated.  */
+             force_fuzzy = (hidden && msgid[0] != '\0' && msgstr[0] != '\0');
+
+             po_callback_message (msgid, &msgid_pos, NULL,
+                                  msgstr, strlen (msgstr) + 1, &msgstr_pos,
+                                  force_fuzzy, false);
+           }
+       }
+    }
+
+  fp = NULL;
+  real_file_name = NULL;
+  gram_pos.line_number = 0;
+}
diff --git a/gettext-tools/src/read-properties.h b/gettext-tools/src/read-properties.h
new file mode 100644 (file)
index 0000000..00fa0fb
--- /dev/null
@@ -0,0 +1,30 @@
+/* Reading Java .properties files.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _READ_PROPERTIES_H
+#define _READ_PROPERTIES_H
+
+#include "read-po-abstract.h"
+
+/* Read a .properties file from a stream, and dispatch to the various
+   abstract_po_reader_class_ty methods.  */
+extern void properties_parse (abstract_po_reader_ty *pop, FILE *fp,
+                             const char *real_filename,
+                             const char *logical_filename);
+
+#endif /* _READ_PROPERTIES_H */
index 0958e9066f3b54886210bd6606924d5a02d738b7..da8c76d04af9d1886b2e32c32dc5372d446100af 100644 (file)
@@ -1018,7 +1018,7 @@ unblock ()
 
 
 int
-msgdomain_write_java (message_list_ty *mlp,
+msgdomain_write_java (message_list_ty *mlp, const char *canon_encoding,
                      const char *resource_name, const char *locale_name,
                      const char *directory,
                      bool assume_java2)
@@ -1040,7 +1040,7 @@ msgdomain_write_java (message_list_ty *mlp,
   retval = 1;
 
   /* Convert the messages to Unicode.  */
-  iconv_message_list (mlp, NULL, po_charset_canonicalize ("UTF-8"), NULL);
+  iconv_message_list (mlp, canon_encoding, po_charset_utf8, NULL);
 
   cleanup_list.tmpdir = NULL;
   cleanup_list.subdir_count = 0;
index 37e1947b7060d5bb9c39cad0ede16dd08976813c..8348956c7d98f7b5f0ea8a4e5a6ec8f7e2717693 100644 (file)
@@ -1,5 +1,5 @@
 /* Writing Java ResourceBundles.
-   Copyright (C) 2001-2002 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
    Return 0 if ok, nonzero on error.  */
 extern int
        msgdomain_write_java (message_list_ty *mlp,
+                            const char *canon_encoding,
                             const char *resource_name,
                             const char *locale_name,
                             const char *directory,
index 862bc2964ecd0c0c4bb300545f73aee36a4ff227..434d190202558ce807f066537265ece52bdadab8 100644 (file)
 #include "po-charset.h"
 #include "linebreak.h"
 #include "msgl-ascii.h"
+#include "write-properties.h"
 #include "xmalloc.h"
 #include "strstr.h"
 #include "exit.h"
+#include "progname.h"
 #include "error.h"
 #include "xerror.h"
 #include "gettext.h"
@@ -373,6 +375,16 @@ message_print_style_escape (bool flag)
 }
 
 
+/* Whether to output a file in Java .properties syntax.  */
+static bool use_syntax_properties = false;
+
+void
+message_print_syntax_properties ()
+{
+  use_syntax_properties = true;
+}
+
+
 /* ================ msgdomain_list_print() and subroutines. ================ */
 
 
@@ -917,52 +929,12 @@ different from yours. Consider using a pure ASCII msgid instead.\n\
 }
 
 
-void
-msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
-                     bool force, bool debug)
+static void
+msgdomain_list_print_po (msgdomain_list_ty *mdlp, FILE *fp, bool debug)
 {
-  FILE *fp;
   size_t j, k;
   bool blank_line;
 
-  /* We will not write anything if, for every domain, we have no message
-     or only the header entry.  */
-  if (!force)
-    {
-      bool found_nonempty = false;
-
-      for (k = 0; k < mdlp->nitems; k++)
-       {
-         message_list_ty *mlp = mdlp->item[k]->messages;
-
-         if (!(mlp->nitems == 0
-               || (mlp->nitems == 1 && mlp->item[0]->msgid[0] == '\0')))
-           {
-             found_nonempty = true;
-             break;
-           }
-       }
-
-      if (!found_nonempty)
-       return;
-    }
-
-  /* Open the output file.  */
-  if (filename != NULL && strcmp (filename, "-") != 0
-      && strcmp (filename, "/dev/stdout") != 0)
-    {
-      fp = fopen (filename, "w");
-      if (fp == NULL)
-       error (EXIT_FAILURE, errno, _("cannot create output file \"%s\""),
-              filename);
-    }
-  else
-    {
-      fp = stdout;
-      /* xgettext:no-c-format */
-      filename = _("standard output");
-    }
-
   /* Write out the messages for each domain.  */
   blank_line = false;
   for (k = 0; k < mdlp->nitems; k++)
@@ -1031,6 +1003,92 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
            blank_line = true;
          }
     }
+}
+
+
+void
+msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
+                     bool force, bool debug)
+{
+  FILE *fp;
+
+  /* We will not write anything if, for every domain, we have no message
+     or only the header entry.  */
+  if (!force)
+    {
+      bool found_nonempty = false;
+      size_t k;
+
+      for (k = 0; k < mdlp->nitems; k++)
+       {
+         message_list_ty *mlp = mdlp->item[k]->messages;
+
+         if (!(mlp->nitems == 0
+               || (mlp->nitems == 1 && mlp->item[0]->msgid[0] == '\0')))
+           {
+             found_nonempty = true;
+             break;
+           }
+       }
+
+      if (!found_nonempty)
+       return;
+    }
+
+  /* Check whether the output format can accomodate all messages.  */
+  if (use_syntax_properties)
+    {
+      if (mdlp->nitems > 1)
+       error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with Java .properties syntax. Try using PO file syntax instead."));
+      if (mdlp->nitems == 1)
+       {
+         message_list_ty *mlp = mdlp->item[0]->messages;
+         const lex_pos_ty *has_plural;
+         size_t j;
+
+         has_plural = NULL;
+         for (j = 0; j < mlp->nitems; j++)
+           {
+             message_ty *mp = mlp->item[j];
+
+             if (mp->msgid_plural != NULL)
+               {
+                 has_plural = &mp->pos;
+                 break;
+               }
+           }
+
+         if (has_plural != NULL)
+           {
+             error_with_progname = false;
+             error_at_line (EXIT_FAILURE, 0,
+                            has_plural->file_name, has_plural->line_number,
+                            _("message catalog has plural form translations, but the output format does not support them. Try generating a Java class using \"msgfmt --java\", instead of a properties file."));
+             error_with_progname = true;
+           }
+       }           
+    }
+
+  /* Open the output file.  */
+  if (filename != NULL && strcmp (filename, "-") != 0
+      && strcmp (filename, "/dev/stdout") != 0)
+    {
+      fp = fopen (filename, "w");
+      if (fp == NULL)
+       error (EXIT_FAILURE, errno, _("cannot create output file \"%s\""),
+              filename);
+    }
+  else
+    {
+      fp = stdout;
+      /* xgettext:no-c-format */
+      filename = _("standard output");
+    }
+
+  if (use_syntax_properties)
+    msgdomain_list_print_properties (mdlp, fp, page_width, debug);
+  else
+    msgdomain_list_print_po (mdlp, fp, debug);
 
   /* Make sure nothing went wrong.  */
   if (fflush (fp) || ferror (fp))
index 261a7840dedc1b6f9e0bf2cc8bb58e95d8f7efbe..a1a81ef4b1fb73afd69e6100d627e1117bf33092 100644 (file)
@@ -48,6 +48,8 @@ extern void
        message_print_style_uniforum (void);
 extern void
        message_print_style_escape (bool flag);
+extern void
+       message_print_syntax_properties (void);
 
 /* Output MDLP into a PO file with the given FILENAME, according to the
    parameters set by the functions above.  */
diff --git a/gettext-tools/src/write-properties.c b/gettext-tools/src/write-properties.c
new file mode 100644 (file)
index 0000000..791a5c0
--- /dev/null
@@ -0,0 +1,291 @@
+/* Writing Java .properties files.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include "write-properties.h"
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "error.h"
+#include "message.h"
+#include "msgl-ascii.h"
+#include "msgl-iconv.h"
+#include "po-charset.h"
+#include "utf8-ucs4.h"
+#include "write-po.h"
+#include "xmalloc.h"
+#include "exit.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+/* The format of the Java .properties files is documented in the JDK
+   documentation for class java.util.Properties.  In the case of .properties
+   files for PropertyResourceBundle, for each message, the msgid becomes the
+   key (left-hand side) and the msgstr becomes the value (right-hand side)
+   of a "key=value" line.  Messages with plurals are not supported in this
+   format.  */
+
+/* Handling of comments: We copy all comments from the PO file to the
+   .properties file. This is not really needed; it's a service for translators
+   who don't like PO files and prefer to maintain the .properties file.  */
+
+/* Converts a string to JAVA encoding (with \uxxxx sequences for non-ASCII
+   characters).  */
+static const char *
+conv_to_java (const char *string)
+{
+  /* We cannot use iconv to "JAVA" because not all iconv() implementations
+     know about the "JAVA" encoding.  */
+  static const char hexdigit[] = "0123456789abcdef";
+  size_t length;
+  char *result;
+
+  if (is_ascii_string (string))
+    return string;
+
+  length = 0;
+  {
+    const char *str = string;
+    const char *str_limit = str + strlen (str);
+
+    while (str < str_limit)
+      {
+       unsigned int uc;
+       str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+       length += (uc <= 0x007f ? 1 : uc < 0x10000 ? 6 : 12);
+      }
+  }
+
+  result = (char *) xmalloc (length + 1);
+
+  {
+    char *newstr = result;
+    const char *str = string;
+    const char *str_limit = str + strlen (str);
+
+    while (str < str_limit)
+      {
+       unsigned int uc;
+       str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+       if (uc <= 0x007f)
+         /* ASCII characters can be output literally.
+            We could treat non-ASCII ISO-8859-1 characters (0x0080..0x00FF)
+            the same way, but there is no point in doing this; Sun's
+            nativetoascii doesn't do it either.  */
+         *newstr++ = uc;
+       else if (uc < 0x10000)
+         {
+           /* Single UCS-2 'char'  */
+           sprintf (newstr, "\\u%c%c%c%c",
+                    hexdigit[(uc >> 12) & 0x0f], hexdigit[(uc >> 8) & 0x0f],
+                    hexdigit[(uc >> 4) & 0x0f], hexdigit[uc & 0x0f]);
+           newstr += 6;
+         }
+       else
+         {
+           /* UTF-16 surrogate: two 'char's.  */
+           unsigned int uc1 = 0xd800 + ((uc - 0x10000) >> 10);
+           unsigned int uc2 = 0xdc00 + ((uc - 0x10000) & 0x3ff);
+           sprintf (newstr, "\\u%c%c%c%c",
+                    hexdigit[(uc1 >> 12) & 0x0f], hexdigit[(uc1 >> 8) & 0x0f],
+                    hexdigit[(uc1 >> 4) & 0x0f], hexdigit[uc1 & 0x0f]);
+           newstr += 6;
+           sprintf (newstr, "\\u%c%c%c%c",
+                    hexdigit[(uc2 >> 12) & 0x0f], hexdigit[(uc2 >> 8) & 0x0f],
+                    hexdigit[(uc2 >> 4) & 0x0f], hexdigit[uc2 & 0x0f]);
+           newstr += 6;
+         }
+      }
+    *newstr = '\0';
+  }
+
+  return result;
+}
+
+/* Writes a key or value to the file, without newline.  */
+static void
+write_escaped_string (FILE *fp, const char *str, bool in_key)
+{
+  static const char hexdigit[] = "0123456789abcdef";
+  const char *str_limit = str + strlen (str);
+  bool first = true;
+
+  while (str < str_limit)
+    {
+      unsigned int uc;
+      str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+      /* Whitespace must be escaped.  */
+      if (uc == 0x0020 && (first || in_key))
+       {
+         putc ('\\', fp);
+         putc (' ', fp);
+       }
+      else if (uc == 0x0009)
+       {
+         putc ('\\', fp);
+         putc ('t', fp);
+       }
+      else if (uc == 0x000a)
+       {
+         putc ('\\', fp);
+         putc ('n', fp);
+       }
+      else if (uc == 0x000d)
+       {
+         putc ('\\', fp);
+         putc ('r', fp);
+       }
+      else if (uc == 0x000c)
+       {
+         putc ('\\', fp);
+         putc ('f', fp);
+       }
+      else if (/* Backslash must be escaped.  */
+              uc == '\\'
+              /* Possible comment introducers must be escaped.  */
+              || uc == '#' || uc == '!'
+              /* Key terminators must be escaped.  */
+              || uc == '=' || uc == ':')
+       {
+         putc ('\\', fp);
+         putc (uc, fp);
+       }
+      else if (uc >= 0x0020 && uc <= 0x007e)
+       {
+         /* ASCII characters can be output literally.
+            We could treat non-ASCII ISO-8859-1 characters (0x0080..0x00FF)
+            the same way, but there is no point in doing this; Sun's
+            nativetoascii doesn't do it either.  */
+         putc (uc, fp);
+       }
+      else if (uc < 0x10000)
+       {
+         /* Single UCS-2 'char'  */
+         fprintf (fp, "\\u%c%c%c%c",
+                  hexdigit[(uc >> 12) & 0x0f], hexdigit[(uc >> 8) & 0x0f],
+                  hexdigit[(uc >> 4) & 0x0f], hexdigit[uc & 0x0f]);
+       }
+      else
+       {
+         /* UTF-16 surrogate: two 'char's.  */
+         unsigned int uc1 = 0xd800 + ((uc - 0x10000) >> 10);
+         unsigned int uc2 = 0xdc00 + ((uc - 0x10000) & 0x3ff);
+         fprintf (fp, "\\u%c%c%c%c",
+                  hexdigit[(uc1 >> 12) & 0x0f], hexdigit[(uc1 >> 8) & 0x0f],
+                  hexdigit[(uc1 >> 4) & 0x0f], hexdigit[uc1 & 0x0f]);
+         fprintf (fp, "\\u%c%c%c%c",
+                  hexdigit[(uc2 >> 12) & 0x0f], hexdigit[(uc2 >> 8) & 0x0f],
+                  hexdigit[(uc2 >> 4) & 0x0f], hexdigit[uc2 & 0x0f]);
+       }
+      first = false;
+    }
+}
+
+/* Writes a message to the file.  */
+static void
+write_message (FILE *fp, const message_ty *mp, size_t page_width, bool debug)
+{
+  /* Print translator comment if available.  */
+  message_print_comment (mp, fp);
+
+  /* Print xgettext extracted comments.  */
+  message_print_comment_dot (mp, fp);
+
+  /* Print the file position comments.  */
+  message_print_comment_filepos (mp, fp, false, page_width);
+
+  /* Print flag information in special comment.  */
+  message_print_comment_flags (mp, fp, debug);
+
+  /* Put a comment mark if the message is the header or untranslated or
+     fuzzy.  */
+  if (mp->msgid[0] == '\0'
+      || mp->msgstr[0] == '\0'
+      || (mp->is_fuzzy && mp->msgid[0] != '\0'))
+    putc ('!', fp);
+
+  /* Now write the untranslated string and the translated string.  */
+  write_escaped_string (fp, mp->msgid, true);
+  putc ('=', fp);
+  write_escaped_string (fp, mp->msgstr, false);
+
+  putc ('\n', fp);
+}
+
+/* Writes an entire message list to the file.  */
+static void
+write_properties (FILE *fp, message_list_ty *mlp, const char *canon_encoding,
+                 size_t page_width, bool debug)
+{
+  bool blank_line;
+  size_t j, i;
+
+  /* Convert the messages to Unicode.  */
+  iconv_message_list (mlp, canon_encoding, po_charset_utf8, NULL);
+  for (j = 0; j < mlp->nitems; ++j)
+    {
+      message_ty *mp = mlp->item[j];
+
+      if (mp->comment != NULL)
+       for (i = 0; i < mp->comment->nitems; ++i)
+         mp->comment->item[i] = conv_to_java (mp->comment->item[i]);
+      if (mp->comment_dot != NULL)
+       for (i = 0; i < mp->comment_dot->nitems; ++i)
+         mp->comment_dot->item[i] = conv_to_java (mp->comment_dot->item[i]);
+    }
+
+  /* Loop through the messages.  */
+  blank_line = false;
+  for (j = 0; j < mlp->nitems; ++j)
+    {
+      const message_ty *mp = mlp->item[j];
+
+      if (mp->msgid_plural == NULL && !mp->obsolete)
+       {
+         if (blank_line)
+           putc ('\n', fp);
+
+         write_message (fp, mp, page_width, debug);
+
+         blank_line = true;
+       }
+    }
+}
+
+/* Output the contents of a PO file in Java .properties syntax.  */
+void
+msgdomain_list_print_properties (msgdomain_list_ty *mdlp, FILE *fp,
+                                size_t page_width, bool debug)
+{
+  message_list_ty *mlp;
+
+  if (mdlp->nitems == 1)
+    mlp = mdlp->item[0]->messages;
+  else
+    mlp = message_list_alloc (false);
+  write_properties (fp, mlp, mdlp->encoding, page_width, debug);
+}
diff --git a/gettext-tools/src/write-properties.h b/gettext-tools/src/write-properties.h
new file mode 100644 (file)
index 0000000..d25be0d
--- /dev/null
@@ -0,0 +1,33 @@
+/* Writing Java .properties files.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _WRITE_PROPERTIES_H
+#define _WRITE_PROPERTIES_H
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include "message.h"
+
+/* Output the contents of a PO file in Java .properties syntax.  */
+extern void
+       msgdomain_list_print_properties (msgdomain_list_ty *mdlp, FILE *fp,
+                                       size_t page_width, bool debug);
+
+#endif /* _WRITE_PROPERTIES_H */
index fed43f5a038d0e671966e1aafcbbec51c2d04864..b99a10372bf95ab54c0edb78cd7b8f1936a3c77e 100644 (file)
@@ -133,7 +133,7 @@ write_msg (FILE *output_file, message_list_ty *mlp, const char *locale_name)
 }
 
 int
-msgdomain_write_tcl (message_list_ty *mlp,
+msgdomain_write_tcl (message_list_ty *mlp, const char *canon_encoding,
                     const char *locale_name,
                     const char *directory)
 {
@@ -161,7 +161,7 @@ but the Tcl message catalog format doesn't support plural handling\n")));
   }
 
   /* Convert the messages to Unicode.  */
-  iconv_message_list (mlp, NULL, po_charset_canonicalize ("UTF-8"), NULL);
+  iconv_message_list (mlp, canon_encoding, po_charset_utf8, NULL);
 
   /* Now create the file.  */
   {
index 2b135db67f6464a83cef6dab04e3280c9545188c..8ebcafb5b62c0ea93bfbc43cf2200300c0ec3599 100644 (file)
@@ -1,5 +1,5 @@
 /* Writing tcl/msgcat .msg files.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2002.
 
    This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,7 @@
    the base directory.
    Return 0 if ok, nonzero on error.  */
 extern int
-       msgdomain_write_tcl (message_list_ty *mlp,
+       msgdomain_write_tcl (message_list_ty *mlp, const char *canon_encoding,
                            const char *locale_name,
                            const char *directory);
 
index f513daa38380789dda10be49ef3454d3bce67d5d..6cc89c78bd42a76fa485377b525bb8722783141d 100644 (file)
@@ -1,4 +1,4 @@
-/* xgettext PO backend.
+/* xgettext PO and JavaProperties backends.
    Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
@@ -47,7 +47,7 @@ extract_add_message (default_po_reader_ty *this,
                     char *msgid_plural,
                     char *msgstr, size_t msgstr_len,
                     lex_pos_ty *msgstr_pos,
-                    bool obsolete)
+                    bool force_fuzzy, bool obsolete)
 {
   /* See whether we shall exclude this message.  */
   if (exclude != NULL && message_list_search (exclude, msgid) != NULL)
@@ -67,7 +67,7 @@ extract_add_message (default_po_reader_ty *this,
 
   /* Invoke superclass method.  */
   default_add_message (this, msgid, msgid_pos, msgid_plural,
-                      msgstr, msgstr_len, msgstr_pos, obsolete);
+                      msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
 }
 
 
@@ -98,10 +98,11 @@ static default_po_reader_class_ty extract_methods =
 };
 
 
-void
-extract_po (FILE *fp,
-           const char *real_filename, const char *logical_filename,
-           msgdomain_list_ty *mdlp)
+static void
+extract (FILE *fp,
+        const char *real_filename, const char *logical_filename,
+        input_syntax_ty syntax,
+        msgdomain_list_ty *mdlp)
 {
   default_po_reader_ty *pop;
 
@@ -113,6 +114,25 @@ extract_po (FILE *fp,
   pop->allow_duplicates_if_same_msgstr = true;
   pop->mdlp = NULL;
   pop->mlp = mdlp->item[0]->messages;
-  po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename);
+  po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename,
+          syntax);
   po_reader_free ((abstract_po_reader_ty *) pop);
 }
+
+
+void
+extract_po (FILE *fp,
+           const char *real_filename, const char *logical_filename,
+           msgdomain_list_ty *mdlp)
+{
+  extract (fp, real_filename,  logical_filename, syntax_po, mdlp);
+}
+
+
+void
+extract_properties (FILE *fp,
+                   const char *real_filename, const char *logical_filename,
+                   msgdomain_list_ty *mdlp)
+{
+  extract (fp, real_filename,  logical_filename, syntax_properties, mdlp);
+}
diff --git a/gettext-tools/src/x-properties.h b/gettext-tools/src/x-properties.h
new file mode 100644 (file)
index 0000000..e9e5f1e
--- /dev/null
@@ -0,0 +1,29 @@
+/* xgettext JavaProperties backend.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+#define EXTENSIONS_PROPERTIES \
+  { "properties", "JavaProperties" },                                  \
+
+#define SCANNERS_PROPERTIES \
+  { "JavaProperties", extract_properties, NULL },                      \
+
+/* Scan a JavaProperties file and add its translatable strings to mdlp.  */
+extern void extract_properties (FILE *fp, const char *real_filename,
+                               const char *logical_filename,
+                               msgdomain_list_ty *mdlp);
index b89e6a61f997bc75c52969330d749da04db514bb..ae113e2f737b3ea8c662790bbb0f1bbba9569ac5 100644 (file)
@@ -70,6 +70,7 @@
 #include "x-librep.h"
 #include "x-smalltalk.h"
 #include "x-java.h"
+#include "x-properties.h"
 #include "x-awk.h"
 #include "x-ycp.h"
 #include "x-tcl.h"
@@ -169,6 +170,7 @@ static const struct option long_options[] =
   { "omit-header", no_argument, &xgettext_omit_header, 1 },
   { "output", required_argument, NULL, 'o' },
   { "output-dir", required_argument, NULL, 'p' },
+  { "properties-output", no_argument, NULL, CHAR_MAX + 6 },
   { "sort-by-file", no_argument, NULL, 'F' },
   { "sort-output", no_argument, NULL, 's' },
   { "strict", no_argument, NULL, 'S' },
@@ -393,6 +395,9 @@ main (int argc, char *argv[])
       case CHAR_MAX + 5:       /* --msgid-bugs-address */
        msgid_bugs_address = optarg;
        break;
+      case CHAR_MAX + 6:       /* --properties-output */
+       message_print_syntax_properties ();
+       break;
       default:
        usage (EXIT_FAILURE);
        /* NOTREACHED */
@@ -644,8 +649,8 @@ Choice of input file language:\n"));
       printf (_("\
   -L, --language=NAME         recognise the specified language\n\
                                 (C, C++, ObjectiveC, PO, Python, Lisp,\n\
-                                EmacsLisp, librep, Smalltalk, Java, awk, YCP,\n\
-                                Tcl, PHP, RST, Glade)\n"));
+                                EmacsLisp, librep, Smalltalk, Java,\n\
+                                JavaProperties, awk, YCP, Tcl, PHP, RST, Glade)\n"));
       printf (_("\
   -C, --c++                   shorthand for --language=C++\n"));
       printf (_("\
@@ -698,6 +703,8 @@ Output details:\n"));
       printf (_("\
       --strict                write out strict Uniforum conforming .po file\n"));
       printf (_("\
+      --properties-output     write out a Java .properties file\n"));
+      printf (_("\
   -w, --width=NUMBER          set output page width\n"));
       printf (_("\
       --no-wrap               do not break long message lines, longer than\n\
@@ -749,7 +756,7 @@ exclude_directive_message (abstract_po_reader_ty *pop,
                           char *msgid_plural,
                           char *msgstr, size_t msgstr_len,
                           lex_pos_ty *msgstr_pos,
-                          bool obsolete)
+                          bool force_fuzzy, bool obsolete)
 {
   message_ty *mp;
 
@@ -802,7 +809,7 @@ read_exclusion_file (char *filename)
   abstract_po_reader_ty *pop;
 
   pop = po_reader_alloc (&exclude_methods);
-  po_scan (pop, fp, real_filename, filename);
+  po_scan (pop, fp, real_filename, filename, input_syntax);
   po_reader_free (pop);
 
   if (fp != stdin)
@@ -1442,6 +1449,7 @@ language_to_extractor (const char *name)
     SCANNERS_LIBREP
     SCANNERS_SMALLTALK
     SCANNERS_JAVA
+    SCANNERS_PROPERTIES
     SCANNERS_AWK
     SCANNERS_YCP
     SCANNERS_TCL
@@ -1489,6 +1497,7 @@ extension_to_language (const char *extension)
     EXTENSIONS_LIBREP
     EXTENSIONS_SMALLTALK
     EXTENSIONS_JAVA
+    EXTENSIONS_PROPERTIES
     EXTENSIONS_AWK
     EXTENSIONS_YCP
     EXTENSIONS_TCL
index 97408b87eec4899350294432b94565a52c2d1f96..a37c54429fb89f2c970938f708fffcfa1ecc9ddb 100644 (file)
@@ -29,8 +29,8 @@
 #include "message.h"
 #include "pos.h"
 
-/* Borrowed from read-po.h.  */
-extern int line_comment;
+/* Declare 'line_comment' and 'input_syntax'.  */
+#include "read-po.h"
 
 /* If true, omit the header entry.
    If false, keep the header entry present in the input.  */
index 87f0ddda303cd2c3582f0a6f7500b386704d8544..40e41ea2fcc3d144a2c78f2b0dbf7abcb07189c7 100644 (file)
@@ -1,3 +1,25 @@
+2003-04-26  Bruno Haible  <bruno@clisp.org>
+
+       * msgattrib-15: New file.
+       * msgcat-11: New file.
+       * msgcat-12: New file.
+       * msgcmp-3: New file.
+       * msgcomm-24: New file.
+       * msgconv-4: New file.
+       * msgen-2: New file.
+       * msgexec-3: New file.
+       * msgfilter-3: New file.
+       * msgfmt-13: New file.
+       * msggrep-6: New file.
+       * msgmerge-23: New file.
+       * msgmerge-24: New file.
+       * msgunfmt-4: New file.
+       * msguniq-4: New file.
+       * xgettext-24: New file.
+       * msguniq-a.inp: New file.
+       * Makefile.am (TESTS): Add the new tests.
+       (EXTRA_DIST): Add msguniq-a.inp.
+
 2003-04-14  Bruno Haible  <bruno@clisp.org>
 
        * Makefile.am (CHECKER): New variable.
index 17aaf6f6218d0a1819c5247b41a5e3c8e22e1a04..01887a20bcf17ce78db7567d8972c559db2980b6 100644 (file)
@@ -23,32 +23,33 @@ EXTRA_DIST =
 TESTS = gettext-1 gettext-2 \
        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-11 msgattrib-12 msgattrib-13 msgattrib-14 msgattrib-15 \
        msgcat-1 msgcat-2 msgcat-3 msgcat-4 msgcat-5 msgcat-6 msgcat-7 \
-       msgcat-8 msgcat-9 msgcat-10 \
-       msgcmp-1 msgcmp-2 \
+       msgcat-8 msgcat-9 msgcat-10 msgcat-11 msgcat-12 \
+       msgcmp-1 msgcmp-2 msgcmp-3 \
        msgcomm-1 msgcomm-2 msgcomm-3 msgcomm-4 msgcomm-5 msgcomm-6 msgcomm-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 \
-       msgconv-1 msgconv-2 msgconv-3 \
-       msgen-1 \
-       msgexec-1 msgexec-2 \
-       msgfilter-1 msgfilter-2 \
+       msgcomm-20 msgcomm-21 msgcomm-22 msgcomm-23 msgcomm-24 \
+       msgconv-1 msgconv-2 msgconv-3 msgconv-4 \
+       msgen-1 msgen-2 \
+       msgexec-1 msgexec-2 msgexec-3 \
+       msgfilter-1 msgfilter-2 msgfilter-3 \
        msgfmt-1 msgfmt-2 msgfmt-3 msgfmt-4 msgfmt-5 msgfmt-6 msgfmt-7 \
-       msgfmt-8 msgfmt-9 msgfmt-10 msgfmt-11 msgfmt-12 \
-       msggrep-1 msggrep-2 msggrep-3 msggrep-4 msggrep-5 \
+       msgfmt-8 msgfmt-9 msgfmt-10 msgfmt-11 msgfmt-12 msgfmt-13 \
+       msggrep-1 msggrep-2 msggrep-3 msggrep-4 msggrep-5 msggrep-6 \
        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 \
-       msgunfmt-1 msgunfmt-2 msgunfmt-3 \
-       msguniq-1 msguniq-2 msguniq-3 \
+       msgmerge-23 msgmerge-24 \
+       msgunfmt-1 msgunfmt-2 msgunfmt-3 msgunfmt-4 \
+       msguniq-1 msguniq-2 msguniq-3 msguniq-4 \
        xgettext-1 xgettext-2 xgettext-3 xgettext-4 xgettext-5 xgettext-6 \
        xgettext-7 xgettext-8 xgettext-9 xgettext-10 xgettext-11 xgettext-12 \
        xgettext-13 xgettext-14 xgettext-15 xgettext-16 xgettext-17 \
        xgettext-18 xgettext-19 xgettext-20 xgettext-21 xgettext-22 \
-       xgettext-23 \
+       xgettext-23 xgettext-24 \
        format-awk-1 format-awk-2 \
        format-c-1 format-c-2 format-c-3 format-c-4 \
        format-elisp-1 format-elisp-2 \
@@ -67,8 +68,8 @@ TESTS = gettext-1 gettext-2 \
        lang-rst
 
 EXTRA_DIST += $(TESTS) \
-       test.mo xg-test1.ok.po mex-test2.ok msguniq-a.in msguniq-a.out \
-       ChangeLog.0
+       test.mo xg-test1.ok.po mex-test2.ok msguniq-a.in msguniq-a.inp \
+       msguniq-a.out ChangeLog.0
 
 XGETTEXT = ../src/xgettext
 
diff --git a/gettext-tools/tests/msgattrib-15 b/gettext-tools/tests/msgattrib-15
new file mode 100755 (executable)
index 0000000..5e6e843
--- /dev/null
@@ -0,0 +1,60 @@
+#! /bin/sh
+
+# Test --translated option with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles ma-test15.properties"
+cat <<\EOF > ma-test15.properties
+# HEADER.
+#
+!=Project-Id-Version\: Bonnie Tyler\n
+
+#: married-men:4
+#, fuzzy
+!The\ world\ is\ full\ of\ married\ men=So viele verheiratete M\u00e4nner
+
+#: married-men:5
+with\ wives\ who\ never\ understand=und ihre Frauen verstehen sie nicht
+
+#: married-men:6
+!They're\ looking\ for\ someone\ to\ share=
+
+# schwer zu \u00fcbersetzen...
+#: married-men:7
+!the\ excitement\ of\ a\ love\ affair=
+
+#: married-men:8
+!Just\ as\ soon\ as\ they\ find\ you=
+
+#: married-men:9
+!They\ warn\ you\ and\ darn\ you=
+EOF
+
+tmpfiles="$tmpfiles ma-test15.out"
+: ${MSGATTRIB=msgattrib}
+${MSGATTRIB} --translated --properties-input --properties-output ma-test15.properties -o ma-test15.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles ma-test15.ok"
+cat <<\EOF > ma-test15.ok
+# HEADER.
+#
+!=Project-Id-Version\: Bonnie Tyler\n
+
+#: married-men:4
+#, fuzzy
+!The\ world\ is\ full\ of\ married\ men=So viele verheiratete M\u00e4nner
+
+#: married-men:5
+with\ wives\ who\ never\ understand=und ihre Frauen verstehen sie nicht
+EOF
+
+: ${DIFF=diff}
+${DIFF} ma-test15.ok ma-test15.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgcat-11 b/gettext-tools/tests/msgcat-11
new file mode 100755 (executable)
index 0000000..8c12b30
--- /dev/null
@@ -0,0 +1,42 @@
+#! /bin/sh
+
+# Test --use-first option with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mcat-test11.in1 mcat-test11.in2"
+cat <<\EOF > mcat-test11.in1
+#. Help text (HTML-like) START
+#: clients/inst_ask_config.ycp:119
+Congratulations\!=Gl\u00fcckwunsch\!
+EOF
+
+cat <<\EOF > mcat-test11.in2
+#. Help text (HTML-like) START
+#: clients/inst_ask_config.ycp:119
+Congratulations\!=Herzlichen Gl\u00fcckwunsch\!
+EOF
+
+tmpfiles="$tmpfiles mcat-test11.out"
+rm -f mcat-test11.out
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --use-first --more-than=0 --properties-input --properties-output \
+    mcat-test11.in1 mcat-test11.in2 -o mcat-test11.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mcat-test11.ok"
+cat << \EOF > mcat-test11.ok
+#. Help text (HTML-like) START
+#: clients/inst_ask_config.ycp:119
+Congratulations\!=Gl\u00fcckwunsch\!
+EOF
+
+: ${DIFF=diff}
+${DIFF} mcat-test11.ok mcat-test11.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgcat-12 b/gettext-tools/tests/msgcat-12
new file mode 100755 (executable)
index 0000000..2c29975
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+# Test conversion from UTF-8 to BIG5 is a NOP with Java .properties syntax.
+# Test that encoding names are case insensitive.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mcat-test12.properties"
+cat <<\EOF > mcat-test12.properties
+#: src/msgcmp.c:155 src/msgmerge.c:273
+exactly\ 2\ input\ files\ required=\u6b64\u529f\u80fd\u9700\u8981\u6070\u597d\u6307\u5b9a\u5169\u500b\u8f38\u5165\u6a94
+EOF
+
+tmpfiles="$tmpfiles mcat-test12.out"
+: ${MSGCAT=msgcat}
+${MSGCAT} --properties-input --properties-output -t Big5 mcat-test12.properties -o mcat-test12.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+: ${DIFF=diff}
+# Redirect stdout, so as not to fill the user's screen with non-ASCII bytes.
+${DIFF} mcat-test12.properties mcat-test12.out >/dev/null
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgcmp-3 b/gettext-tools/tests/msgcmp-3
new file mode 100755 (executable)
index 0000000..00dfedb
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/sh
+
+# Test a failing comparison with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mc-test3.in1 mc-test3.in2"
+cat <<EOF > mc-test3.in1
+one=first
+two=second
+three=third
+four=fourth
+EOF
+
+cat <<EOF > mc-test3.in2
+!thre=
+!one=
+!two=
+EOF
+
+tmpfiles="$tmpfiles mc-test3.out"
+: ${MSGCMP=msgcmp}
+LC_MESSAGES=C LC_ALL= \
+${MSGCMP} --properties-input mc-test3.in1 mc-test3.in2 2>&1 | grep -v '^==' > mc-test3.out
+
+tmpfiles="$tmpfiles mc-test3.ok"
+cat <<EOF > mc-test3.ok
+mc-test3.in2:1: this message is used but not defined...
+mc-test3.in1:3: ...but this definition is similar
+mc-test3.in1:4: warning: this message is not used
+msgcmp: found 1 fatal error
+EOF
+
+: ${DIFF=diff}
+${DIFF} mc-test3.ok mc-test3.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgcomm-24 b/gettext-tools/tests/msgcomm-24
new file mode 100755 (executable)
index 0000000..c7c6a43
--- /dev/null
@@ -0,0 +1,39 @@
+#! /bin/sh
+
+# Test --more-than=0 option with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mcomm-test24.in1 mcomm-test24.in2"
+cat <<EOF > mcomm-test24.in1
+#: first.c:123
+1=1x
+EOF
+
+cat <<EOF > mcomm-test24.in2
+#: hunt.c:759
+2=2x
+EOF
+
+tmpfiles="$tmpfiles mcomm-test24.out"
+: ${MSGCOMM=msgcomm}
+${MSGCOMM} --more-than=0 --properties-input --properties-output -o mcomm-test24.out mcomm-test24.in1 mcomm-test24.in2
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mcomm-test24.ok"
+cat << EOF > mcomm-test24.ok
+#: first.c:123
+1=1x
+
+#: hunt.c:759
+2=2x
+EOF
+
+: ${DIFF=diff}
+${DIFF} mcomm-test24.ok mcomm-test24.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgconv-4 b/gettext-tools/tests/msgconv-4
new file mode 100755 (executable)
index 0000000..29b82a9
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+# Test conversion from UTF-8 to BIG5 is a NOP with Java .properties syntax.
+# Test that encoding names are case insensitive.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mco-test4.properties"
+cat <<\EOF > mco-test4.properties
+#: src/msgcmp.c:155 src/msgmerge.c:273
+exactly\ 2\ input\ files\ required=\u6b64\u529f\u80fd\u9700\u8981\u6070\u597d\u6307\u5b9a\u5169\u500b\u8f38\u5165\u6a94
+EOF
+
+tmpfiles="$tmpfiles mco-test4.out"
+: ${MSGCONV=msgconv}
+${MSGCONV} --properties-input --properties-output -t Big5 mco-test4.properties -o mco-test4.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+: ${DIFF=diff}
+# Redirect stdout, so as not to fill the user's screen with non-ASCII bytes.
+${DIFF} mco-test4.properties mco-test4.out >/dev/null
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgen-2 b/gettext-tools/tests/msgen-2
new file mode 100755 (executable)
index 0000000..634940f
--- /dev/null
@@ -0,0 +1,37 @@
+#! /bin/sh
+
+# Test general operation with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles men-test2.properties"
+cat <<\EOF > men-test2.properties
+!height\ must\ be\ positive=
+
+color\ cannot\ be\ transparent=colour cannot be transparent
+
+width\ must\ be\ positive=
+EOF
+
+tmpfiles="$tmpfiles men-test2.out"
+: ${MSGEN=msgen}
+${MSGEN} --properties-input --properties-output men-test2.properties -o men-test2.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles men-test2.ok"
+cat <<\EOF > men-test2.ok
+height\ must\ be\ positive=height must be positive
+
+color\ cannot\ be\ transparent=colour cannot be transparent
+
+width\ must\ be\ positive=width must be positive
+EOF
+
+: ${DIFF=diff}
+${DIFF} men-test2.ok men-test2.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgexec-3 b/gettext-tools/tests/msgexec-3
new file mode 100755 (executable)
index 0000000..0f46b89
--- /dev/null
@@ -0,0 +1,93 @@
+#! /bin/sh
+
+# Test of an external command with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mex-test3.properties"
+cat <<\EOF > mex-test3.properties
+# HEADER.
+#
+!=Project-Id-Version\: Bonnie Tyler\n
+
+#: married-men:4
+#, fuzzy
+!The\ world\ is\ full\ of\ married\ men=So viele verheiratete M\u00e4nner
+
+#: married-men:5
+with\ wives\ who\ never\ understand=und ihre Frauen verstehen sie nicht
+
+#: married-men:6
+!They're\ looking\ for\ someone\ to\ share=
+
+# schwer zu \u00fcbersetzen...
+#: married-men:7
+!the\ excitement\ of\ a\ love\ affair=
+
+#: married-men:8
+!Just\ as\ soon\ as\ they\ find\ you=
+
+#: married-men:9
+!They\ warn\ you\ and\ darn\ you=
+EOF
+
+tmpfiles="$tmpfiles mex-test3.sh"
+cat <<\EOF > mex-test3.sh
+#! /bin/sh
+echo "========================= $MSGEXEC_LOCATION ========================="
+cat <<MEOF
+$MSGEXEC_MSGID
+---
+MEOF
+cat
+echo
+exit 0
+EOF
+chmod a+x mex-test3.sh
+
+tmpfiles="$tmpfiles mex-test3.out"
+: ${MSGEXEC=msgexec}
+${MSGEXEC} --properties-input -i mex-test3.properties ./mex-test3.sh > mex-test3.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mex-test3.ok"
+cat <<\EOF > mex-test3.ok
+========================= mex-test3.properties:3 =========================
+
+---
+Project-Id-Version: Bonnie Tyler
+
+========================= mex-test3.properties:7 =========================
+The world is full of married men
+---
+So viele verheiratete Männer
+========================= mex-test3.properties:10 =========================
+with wives who never understand
+---
+und ihre Frauen verstehen sie nicht
+========================= mex-test3.properties:13 =========================
+They're looking for someone to share
+---
+
+========================= mex-test3.properties:17 =========================
+the excitement of a love affair
+---
+
+========================= mex-test3.properties:20 =========================
+Just as soon as they find you
+---
+
+========================= mex-test3.properties:23 =========================
+They warn you and darn you
+---
+
+EOF
+
+: ${DIFF=diff}
+${DIFF} mex-test3.ok mex-test3.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgfilter-3 b/gettext-tools/tests/msgfilter-3
new file mode 100755 (executable)
index 0000000..e0c47fe
--- /dev/null
@@ -0,0 +1,97 @@
+#! /bin/sh
+
+# Test general filter execution with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  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 || { rm -fr $tmpfiles; 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 || { rm -fr $tmpfiles; exit 77; }
+
+tmpfiles="$tmpfiles mfi-test3.properties"
+cat <<\EOF > mfi-test3.properties
+# HEADER.
+#
+!=Project-Id-Version\: Bonnie Tyler\n
+
+#: married-men:4
+#, fuzzy
+!The\ world\ is\ full\ of\ married\ men=So viele verheiratete M\u00e4nner
+
+#: married-men:5
+with\ wives\ who\ never\ understand=und ihre Frauen verstehen sie nicht
+
+#: married-men:6
+!They're\ looking\ for\ someone\ to\ share=
+
+# schwer zu \u00fcbersetzen...
+#: married-men:7
+!the\ excitement\ of\ a\ love\ affair=
+
+#: married-men:8
+!Just\ as\ soon\ as\ they\ find\ you=
+
+#: married-men:9
+!They\ warn\ you\ and\ darn\ you=
+EOF
+
+tmpfiles="$tmpfiles mfi-test3.out"
+: ${MSGFILTER=msgfilter}
+LC_ALL=C \
+${MSGFILTER} --properties-input --properties-output -i mfi-test3.properties -o mfi-test3.out fold -b -s -w 20
+result=$?
+test $result = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mfi-test3.ok"
+cat <<\EOF > mfi-test3.ok
+# HEADER.
+#
+!=Project-Id-Version\: \nBonnie Tyler\n
+
+#: married-men:4
+#, fuzzy
+!The\ world\ is\ full\ of\ married\ men=So viele \nverheiratete M\u00e4nner
+
+#: married-men:5
+with\ wives\ who\ never\ understand=und ihre Frauen \nverstehen sie nicht
+
+#: married-men:6
+!They're\ looking\ for\ someone\ to\ share=
+
+# schwer zu \u00fcbersetzen...
+#: married-men:7
+!the\ excitement\ of\ a\ love\ affair=
+
+#: married-men:8
+!Just\ as\ soon\ as\ they\ find\ you=
+
+#: married-men:9
+!They\ warn\ you\ and\ darn\ you=
+EOF
+
+: ${DIFF=diff}
+${DIFF} mfi-test3.ok mfi-test3.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgfmt-13 b/gettext-tools/tests/msgfmt-13
new file mode 100755 (executable)
index 0000000..e7a52f4
--- /dev/null
@@ -0,0 +1,61 @@
+#! /bin/sh
+
+# Test basic functioning with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles LC_MESSAGES"
+test -d LC_MESSAGES || mkdir LC_MESSAGES
+
+tmpfiles="$tmpfiles module1.properties module2.properties"
+cat <<\EOF > module1.properties
+SYS_(C)\n=MSGFMT(3) portable message object file compiler\nCopyright (C) 1995 Free Software Foundation\nReport bugs to <bug-gnu-utils@gnu.org>\n
+msg\ 1=msg 1 translation
+help\ 2\ %d=help 2 translation
+error\ 3=error 3 translation
+EOF
+
+cat <<\EOF > module2.properties
+# ---
+mesg\ 4=mesg 4 translation
+error\ 3=alternate error 3 translation
+error\ 5=error 5 translation
+window\ 6=window 6 translation
+EOF
+
+# Without use of msgcat, expect a "duplicate message definition" error.
+: ${MSGFMT=msgfmt}
+if ${MSGFMT} --properties-input module1.properties module2.properties -o LC_MESSAGES/gen.mo 2> /dev/null; then
+  rm -fr $tmpfiles
+  exit 1
+fi
+
+# With msgcat, it should work.
+tmpfiles="$tmpfiles modules.properties"
+: ${MSGCAT=msgcat} ${MSGFMT=msgfmt}
+${MSGCAT} --properties-input --properties-output --use-first module1.properties module2.properties -o modules.properties
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+${MSGFMT} --properties-input modules.properties -o LC_MESSAGES/gen.mo
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mf-test1.out"
+: ${GETTEXT=gettext}
+TEXTDOMAINDIR=.. LANGUAGE=tests \
+${GETTEXT} --env LC_ALL=en gen 'SYS_(C)
+' > mf-test1.out
+
+tmpfiles="$tmpfiles gtmf-test1.ok"
+cat <<EOF > gtmf-test1.ok
+MSGFMT(3) portable message object file compiler
+Copyright (C) 1995 Free Software Foundation
+Report bugs to <bug-gnu-utils@gnu.org>
+EOF
+
+: ${DIFF=diff}
+${DIFF} gtmf-test1.ok mf-test1.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msggrep-6 b/gettext-tools/tests/msggrep-6
new file mode 100755 (executable)
index 0000000..a759726
--- /dev/null
@@ -0,0 +1,155 @@
+#! /bin/sh
+
+# Test --msgid and --msgstr options with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mg-test6.properties"
+cat <<\EOF > mg-test6.properties
+#: argmatch.c:141
+#, c-format
+invalid\ argument\ `%s'\ for\ `%s'=ung\u00fcltiges Argument \u00bb%s\u00ab f\u00fcr \u00bb%s\u00ab
+
+#: argmatch.c:142
+#, c-format
+ambiguous\ argument\ `%s'\ for\ `%s'=mehrdeutiges Argument \u00bb%s\u00ab f\u00fcr \u00bb%s\u00ab
+
+#: argmatch.c:162
+Valid\ arguments\ are\:=G\u00fcltige Argumente sind\:
+
+#: copy-file.c:60
+#, c-format
+error\ while\ opening\ "%s"\ for\ reading=\u00d6ffnen der Datei \u00bb%s\u00ab zum Lesen fehlgeschlagen
+
+#: copy-file.c:67
+#, c-format
+cannot\ open\ backup\ file\ "%s"\ for\ writing=\u00d6ffnen der Sicherungsdatei \u00bb%s\u00ab zum Schreiben fehlgeschlagen
+
+#: copy-file.c:80
+#, c-format
+error\ reading\ "%s"=Fehler beim Lesen von \u00bb%s\u00ab
+
+#: copy-file.c:86 copy-file.c:90
+#, c-format
+error\ writing\ "%s"=Fehler beim Schreiben von \u00bb%s\u00ab
+
+#: copy-file.c:92
+#, c-format
+error\ after\ reading\ "%s"=Fehler nach dem Lesen von \u00bb%s\u00ab
+
+#: error.c:115
+Unknown\ system\ error=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
+%s\ subprocess\ failed=Subprozess %s fehlgeschlagen
+
+#: getopt.c:691
+#, c-format
+%s\:\ option\ `%s'\ is\ ambiguous\n=%s\: Option \u00bb%s\u00ab ist mehrdeutig\n
+
+#: getopt.c:716
+#, c-format
+%s\:\ option\ `--%s'\ doesn't\ allow\ an\ argument\n=%s\: Option \u00bb--%s\u00ab erwartet kein Argument\n
+
+#: getopt.c:721
+#, c-format
+%s\:\ option\ `%c%s'\ doesn't\ allow\ an\ argument\n=%s\: Option \u00bb%c%s\u00ab erwartet kein Argument\n
+
+#: getopt.c:739 getopt.c:912
+#, c-format
+%s\:\ option\ `%s'\ requires\ an\ argument\n=%s\: Option \u00bb%s\u00ab erwartet ein Argument\n
+
+#: getopt.c:768
+#, c-format
+%s\:\ unrecognized\ option\ `--%s'\n=%s\: unbekannte Option \u00bb--%s\u00ab\n
+
+#: getopt.c:772
+#, c-format
+%s\:\ unrecognized\ option\ `%c%s'\n=%s\: unbekannte Option \u00bb%c%s\u00ab\n
+
+#: getopt.c:798
+#, c-format
+%s\:\ illegal\ option\ --\ %c\n=%s\: unzul\u00e4ssige Option -- %c\n
+
+#: getopt.c:801
+#, c-format
+%s\:\ invalid\ option\ --\ %c\n=%s\: ung\u00fcltige Option -- %c\n
+
+#: getopt.c:831 getopt.c:961
+#, c-format
+%s\:\ option\ requires\ an\ argument\ --\ %c\n=%s\: Option erwartet ein Argument -- %c\n
+
+#: getopt.c:878
+#, c-format
+%s\:\ option\ `-W\ %s'\ is\ ambiguous\n=%s\: Option \u00bb-W %s\u00ab ist mehrdeutig\n
+
+#: getopt.c:896
+#, c-format
+%s\:\ option\ `-W\ %s'\ doesn't\ allow\ an\ argument\n=%s\: Option \u00bb-W %s\u00ab erwartet kein Argument\n
+
+#: javacomp.c:465
+Java\ compiler\ not\ found,\ try\ installing\ gcj\ or\ set\ $JAVAC=Java-Compiler nicht gefunden; bitte \u00bbgcj\u00ab installieren oder $JAVAC setzen
+
+#: javaexec.c:404
+Java\ virtual\ machine\ not\ found,\ try\ installing\ gij\ or\ set\ $JAVA=Virtuelle Java-Maschine nicht gefunden; bitte \u00bbgcj\u00ab installieren oder\n$JAVA setzen
+
+#: obstack.c:474 xerror.c:75 xmalloc.c:56
+memory\ exhausted=virtueller Speicher ersch\u00f6pft
+
+#: pipe-bidi.c:119 pipe-bidi.c:121 pipe-in.c:136 pipe-out.c:136
+cannot\ create\ pipe=Es ist nicht m\u00f6glich, eine Pipe zu erzeugen
+
+#: wait-process.c:117
+#, c-format
+%s\ subprocess=Subprozess %s
+
+#: wait-process.c:129
+#, c-format
+%s\ subprocess\ got\ fatal\ signal=Subprozess %s hat ein fatales Signal erhalten
+
+# A pattern specified for the msgid only must not be matched with the msgstr.
+GSG-9=Antiterror-Einheit
+EOF
+
+tmpfiles="$tmpfiles mg-test6.out"
+: ${MSGGREP=msggrep}
+LC_MESSAGES=C LC_ALL= \
+${MSGGREP} --properties-input --properties-output -K -e error -T -e Speicher mg-test6.properties -o mg-test6.out
+result=$?
+test $result = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mg-test6.ok"
+cat <<\EOF > mg-test6.ok
+#: copy-file.c:60
+#, c-format
+error\ while\ opening\ "%s"\ for\ reading=\u00d6ffnen der Datei \u00bb%s\u00ab zum Lesen fehlgeschlagen
+
+#: copy-file.c:80
+#, c-format
+error\ reading\ "%s"=Fehler beim Lesen von \u00bb%s\u00ab
+
+#: copy-file.c:86 copy-file.c:90
+#, c-format
+error\ writing\ "%s"=Fehler beim Schreiben von \u00bb%s\u00ab
+
+#: copy-file.c:92
+#, c-format
+error\ after\ reading\ "%s"=Fehler nach dem Lesen von \u00bb%s\u00ab
+
+#: error.c:115
+Unknown\ system\ error=Unbekannter Systemfehler
+
+#: obstack.c:474 xerror.c:75 xmalloc.c:56
+memory\ exhausted=virtueller Speicher ersch\u00f6pft
+EOF
+
+: ${DIFF=diff}
+${DIFF} mg-test6.ok mg-test6.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgmerge-23 b/gettext-tools/tests/msgmerge-23
new file mode 100755 (executable)
index 0000000..27304e9
--- /dev/null
@@ -0,0 +1,60 @@
+#! /bin/sh
+
+# Test handling of obsolete/untranslated messages with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mm-test23.in1 mm-test23.in2"
+cat <<EOF > mm-test23.in1
+#
+# def.po
+#
+#: file:100
+not\ existing=but with translation
+
+#: file2:101
+!not\ existing\ without\ translation=
+
+#: file3:102
+still\ existing=translation
+
+#
+# trailing comments should be removed
+EOF
+
+cat <<EOF > mm-test23.in2
+#
+# ref.po
+#
+#: file3:102
+still\ existing=here is normally no comment
+
+#: file4:10
+!untranslated=
+
+#
+# trailing comments should be removed, even here
+EOF
+
+tmpfiles="$tmpfiles mm-test23.out"
+: ${MSGMERGE=msgmerge}
+${MSGMERGE} -q --properties-input --properties-output mm-test23.in1 mm-test23.in2 -o mm-test23.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mm-test23.ok"
+cat << EOF > mm-test23.ok
+#: file3:102
+still\ existing=translation
+
+#: file4:10
+!untranslated=
+EOF
+
+: ${DIFF=diff}
+${DIFF} mm-test23.ok mm-test23.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgmerge-24 b/gettext-tools/tests/msgmerge-24
new file mode 100755 (executable)
index 0000000..9344d79
--- /dev/null
@@ -0,0 +1,40 @@
+#! /bin/sh
+
+# Test --update: location changed, and xgettext comment added. Both changes
+# must be reflected in the resulting PO file. With Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mm-test24.po"
+cat <<\EOF > mm-test24.po
+#: cogarithmetic.cc:12
+white=wei\u00df
+EOF
+
+tmpfiles="$tmpfiles mm-test24.pot"
+cat <<EOF > mm-test24.pot
+#. location changed
+#: cogarithmetic.cc:33
+!white=
+EOF
+
+tmpfiles="$tmpfiles mm-test24.po~"
+: ${MSGMERGE=msgmerge}
+${MSGMERGE} -q --properties-input --update mm-test24.po mm-test24.pot
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mm-test24.ok"
+cat <<\EOF > mm-test24.ok
+#. location changed
+#: cogarithmetic.cc:33
+white=wei\u00df
+EOF
+
+: ${DIFF=diff}
+${DIFF} mm-test24.ok mm-test24.po
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msgunfmt-4 b/gettext-tools/tests/msgunfmt-4
new file mode 100755 (executable)
index 0000000..1f87de8
--- /dev/null
@@ -0,0 +1,43 @@
+#! /bin/sh
+
+# Test of general operation with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles mu-test4.in"
+cat <<EOF > mu-test4.in
+eight=eighth
+
+five=fifth
+
+four=fourth
+
+one=first
+
+seven=seventh
+
+six=sixth
+
+three=third
+
+two=second
+EOF
+
+tmpfiles="$tmpfiles mu-test4.mo"
+: ${MSGFMT=msgfmt}
+${MSGFMT} --properties-input mu-test4.in -o mu-test4.mo
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles mu-test4.out"
+: ${MSGUNFMT=msgunfmt}
+${MSGUNFMT} --properties-output mu-test4.mo -o mu-test4.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+: ${DIFF=diff}
+${DIFF} mu-test4.in mu-test4.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msguniq-4 b/gettext-tools/tests/msguniq-4
new file mode 100755 (executable)
index 0000000..352e8cf
--- /dev/null
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+# Test general operation with Java .properties syntax.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles msguniq-4.out"
+: ${MSGUNIQ-msguniq}
+${MSGUNIQ} --properties-input --properties-output -w 1000 ${top_srcdir}/tests/msguniq-a.inp -o msguniq-4.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles msguniq-4.ok"
+: ${MSGCAT-msgcat}
+${MSGCAT} --properties-output -w 1000 ${top_srcdir}/tests/msguniq-a.out -o msguniq-4.ok
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+: ${DIFF=diff}
+${DIFF} msguniq-4.ok msguniq-4.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/gettext-tools/tests/msguniq-a.inp b/gettext-tools/tests/msguniq-a.inp
new file mode 100644 (file)
index 0000000..2111197
--- /dev/null
@@ -0,0 +1,4286 @@
+# Template messages for CLISP
+# Copyright (C) 1992-2001 Bruno Haible, Michael Stoll, Marcus Daniels
+# Bruno Haible <haible@clisp.cons.org>, 2001.
+#
+!=Project-Id-Version\: clisp 2.25.1\nPOT-Creation-Date\: 2001-07-21 21\:09\:38 CEST\nPO-Revision-Date\: 2001-07-21 21\:09\:38 CEST\nLast-Translator\: Automatically generated <bruno@linuix>\nLanguage-Team\: Template <xx@li.org>\nMIME-Version\: 1.0\nContent-Type\: text/plain; charset\=UTF-8\nContent-Transfer-Encoding\: 8bit\n
+
+#: constobj.d:376
+!Please\ choose\:=
+
+#: constobj.d:380
+!Please\ choose\ one\ of\ ~\:{~A~\:^,\ ~}\ .=
+
+#: constobj.d:383
+!symbol\ ~A\ from\ \#<PACKAGE\ ~A>\ will\ become\ a\ shadowing\ symbol=
+
+#: constobj.d:385
+!You\ may\ choose\ the\ symbol\ in\ favour\ of\ which\ to\ resolve\ the\ conflict.=
+
+#: constobj.d:387
+!uninterning\ ~S\ from\ ~S\ uncovers\ a\ name\ conflict.=
+
+#: constobj.d:389 constobj.d:403
+!You\ may\ choose\ how\ to\ proceed.=
+
+#: constobj.d:391
+!importing\ ~S\ into\ ~S\ produces\ a\ name\ conflict\ with\ ~S.=
+
+#: constobj.d:393
+!importing\ ~S\ into\ ~S\ produces\ a\ name\ conflict\ with\ ~S\ and\ other\ symbols.=
+
+#: constobj.d:395
+!(("I"\ "import\ it\ and\ unintern\ the\ other\ symbol"\ T)\ ("N"\ "do\ not\ import\ it,\ leave\ undone"\ NIL))=
+
+#: constobj.d:398
+!(("I"\ "import\ it,\ unintern\ one\ other\ symbol\ and\ shadow\ the\ other\ symbols"\ T)\ ("N"\ "do\ not\ import\ it,\ leave\ undone"\ NIL))=
+
+#: constobj.d:401
+!(("I"\ "import\ it\ and\ shadow\ the\ other\ symbol"\ T)\ ("N"\ "do\ nothing"\ NIL))=
+
+#: constobj.d:405
+!symbol\ ~S\ should\ be\ imported\ into\ ~S\ before\ being\ exported.=
+
+#: constobj.d:407
+!(("I"\ "import\ the\ symbol\ first"\ T)\ ("N"\ "do\ nothing,\ don't\ export\ the\ symbol"\ NIL))=
+
+#: constobj.d:410
+!You\ may\ choose\ in\ favour\ of\ which\ symbol\ to\ resolve\ the\ conflict.=
+
+#: constobj.d:412
+!exporting\ ~S\ from\ ~S\ produces\ a\ name\ conflict\ with\ ~S\ from\ ~S.=
+
+#: constobj.d:414
+!Which\ symbol\ should\ be\ accessible\ in\ ~S\ ?=
+
+#: constobj.d:418
+!the\ symbol\ to\ export,\ =
+
+#: constobj.d:420
+!the\ old\ symbol,\ =
+
+#: constobj.d:422
+!You\ may\ choose\ for\ every\ conflict\ in\ favour\ of\ which\ symbol\ to\ resolve\ it.=
+
+#: constobj.d:424
+!~S\ name\ conflicts\ while\ executing\ USE-PACKAGE\ of\ ~S\ into\ package\ ~S.=
+
+#: constobj.d:426
+!which\ symbol\ with\ name\ ~S\ should\ be\ accessible\ in\ ~S\ ?=
+
+#: constobj.d:428
+!You\ can\ input\ another\ name.=
+
+#: constobj.d:430
+!You\ can\ input\ another\ nickname.=
+
+#: constobj.d:432
+!a\ package\ with\ name\ ~S\ already\ exists.=
+
+#: constobj.d:434
+!Please\ input\ new\ package\ name\:=
+
+#: constobj.d:436
+!Please\ input\ new\ package\ nickname\:=
+
+#: constobj.d:438
+!Ignore.=
+
+#: constobj.d:440
+!~S\:\ There\ is\ no\ package\ with\ name\ ~S.=
+
+#: constobj.d:442
+!~*Nevertheless\ delete\ ~S.=
+
+#: constobj.d:444
+!~S\:\ ~S\ is\ used\ by\ ~{~S~^,\ ~}.=
+
+#: constobj.d:472
+!ANSI\ C\ program=
+
+#: constobj.d:476
+!GNU\ C++\ =
+
+#: constobj.d:479
+!GNU\ C\ =
+
+#: constobj.d:486
+!C++\ compiler=
+
+#: constobj.d:489
+!C\ compiler=
+
+#: constobj.d:494
+!ENGLISH=
+
+#: constobj.d:510
+!Continue\ execution=
+
+#: constobj.d:512
+!~S\:\ User\ break=
+
+#: constobj.d:662
+!The\ value\ of\ ~S\ was\ not\ a\ pathname.\ ~\:*~S\ is\ being\ reset.=
+
+#: constobj.d:667
+!Creating\ directory\:\ =
+
+#: constobj.d:824
+!The\ variable\ ~S\ had\ an\ illegal\ value.\n~S\ has\ been\ reset\ to\ ~S.=
+
+#: constobj.d:826
+!Floating\ point\ operation\ combines\ numbers\ of\ different\ precision.\nSee\ ANSI\ CL\ 12.1.4.4\ and\ the\ CLISP\ impnotes\ for\ details.\nThe\ result's\ actual\ precision\ is\ controlled\ by\n~S.\nTo\ shut\ off\ this\ warning,\ set\ ~S\ to\ ~S.=
+
+#: constobj.d:841
+!Bye.=
+
+#: constobj.d:843
+!Press\ a\ key\ to\ terminate...=
+
+#: constobj.d:848
+!\n\ \ Next\ environment\:\ =
+
+#: constobj.d:850
+!\nAPPLY\ frame\ with\ breakpoint\ for\ call\ =
+
+#: constobj.d:852
+!\nAPPLY\ frame\ for\ call\ =
+
+#: constobj.d:854
+!\nEVAL\ frame\ with\ breakpoint\ for\ form\ =
+
+#: constobj.d:856
+!\nEVAL\ frame\ for\ form\ =
+
+#: constobj.d:858
+!\nframe\ binding\ variables\ (~\ \=\ dynamically)\:=
+
+#: constobj.d:861
+!\nCALLBACK\ frame=
+
+#: constobj.d:864
+!\nframe\ binding\ variables\ =
+
+#: constobj.d:866
+!\nframe\ binding\ functions\ =
+
+#: constobj.d:868
+!\ binds\ (~\ \=\ dynamically)\:=
+
+#: constobj.d:871
+!\nblock\ frame\ =
+
+#: constobj.d:873
+!\nnested\ block\ frame\ =
+
+#: constobj.d:875
+!\ for\ =
+
+#: constobj.d:877
+!\ncompiled\ block\ frame\ for\ =
+
+#: constobj.d:879
+!\ntagbody\ frame\ =
+
+#: constobj.d:881
+!\nnested\ tagbody\ frame\ =
+
+#: constobj.d:883
+!\ for=
+
+#: constobj.d:886
+!\ncompiled\ tagbody\ frame\ for\ =
+
+#: constobj.d:888
+!\ncatch\ frame\ for\ tag\ =
+
+#: constobj.d:890
+!\nhandler\ frame\ for\ conditions=
+
+#: constobj.d:892
+!\nunwind-protect\ frame=
+
+#: constobj.d:894
+!\n\ndriver\ frame=
+
+#: constobj.d:896
+!\nframe\ binding\ environments=
+
+#: spvw.d:595
+!could\ not\ make\ symbol\ value\ per-thread=
+
+#: spvw.d:659
+!\n***\ -\ Program\ stack\ overflow.\ RESET=
+
+#: spvw.d:664
+!\n***\ -\ Lisp\ stack\ overflow.\ RESET=
+
+#: spvw.d:801
+!internal\ error\:\ statement\ in\ file\ ~,\ line\ ~\ has\ been\ reached\!\!\nPlease\ send\ the\ authors\ of\ the\ program\ a\ description\ how\ you\ produced\ this\ error\!=
+
+#: spvw.d:863
+!Unknown\ signature\ of\ an\ FSUBR\n=
+
+#: spvw.d:972
+!Unknown\ signature\ of\ a\ SUBR\n=
+
+#: spvw.d:1614
+!module\ `%s'\ requires\ package\ %s.\n=
+
+#: spvw.d:1655
+!GNU\ CLISP\ (http\://clisp.cons.org/)\ is\ an\ ANSI\ Common\ Lisp.\nUsage\:\ \ =
+
+#: spvw.d:1658
+!\ [options]\ [lispfile\ [argument\ ...]]\n\ When\ `lispfile'\ is\ given,\ it\ is\ loaded\ and\ `*ARGS*'\ is\ set\n\ to\ the\ list\ of\ argument\ strings.\ Otherwise,\ an\ interactive\n\ read-eval-print\ loop\ is\ entered.\n=
+
+#: spvw.d:1662
+!Informative\ output\:\n=
+
+#: spvw.d:1663
+!\ -h,\ --help\ \ -\ print\ this\ help\ and\ exit\n=
+
+#: spvw.d:1664
+!\ --version\ \ \ -\ print\ the\ version\ information\n=
+
+#: spvw.d:1665
+!\ --license\ \ \ -\ print\ the\ licensing\ information\n=
+
+#: spvw.d:1666
+!Memory\ image\ selection\:\n=
+
+#: spvw.d:1667
+!\ -B\ lisplibdir\ -\ set\ the\ installation\ directory\n=
+
+#: spvw.d:1669
+!\ -K\ linkingset\ -\ use\ this\ executable\ and\ memory\ image\n=
+
+#: spvw.d:1671
+!\ -M\ memfile\ \ -\ use\ this\ memory\ image\n=
+
+#: spvw.d:1672
+!\ -m\ size\ \ \ \ \ -\ memory\ size\ (size\ \=\ xxxxxxxB\ or\ xxxxKB\ or\ xMB)\n=
+
+#: spvw.d:1674
+!\ -s\ size\ \ \ \ \ -\ stack\ size\ (size\ \=\ xxxxxxxB\ or\ xxxxKB\ or\ xMB)\n=
+
+#: spvw.d:1677
+!\ -t\ tmpdir\ \ \ -\ temporary\ directory\ for\ memmap\n=
+
+#: spvw.d:1679
+!Internationalization\:\n=
+
+#: spvw.d:1680
+!\ -L\ language\ -\ set\ user\ language\n=
+
+#: spvw.d:1681
+!\ -N\ nlsdir\ \ \ -\ NLS\ catalog\ directory\n=
+
+#: spvw.d:1682
+!\ -Edomain\ encoding\ -\ set\ encoding\n=
+
+#: spvw.d:1683
+!Interoperability\:\n=
+
+#: spvw.d:1684
+!\ -q,\ --quiet,\ --silent\ -\ do\ not\ print\ the\ banner\n=
+
+#: spvw.d:1685
+!\ -w\ \ \ \ \ \ \ \ \ \ -\ wait\ for\ keypress\ after\ program\ termination\n=
+
+#: spvw.d:1686
+!\ -I\ \ \ \ \ \ \ \ \ \ -\ be\ ILISP-friendly\n=
+
+#: spvw.d:1687
+!Startup\ actions\:\n=
+
+#: spvw.d:1688
+!\ -a\ \ \ \ \ \ \ \ \ \ -\ more\ ANSI\ CL\ compliance\n=
+
+#: spvw.d:1689
+!\ -p\ package\ \ -\ start\ in\ the\ package\n=
+
+#: spvw.d:1690
+!\ -C\ \ \ \ \ \ \ \ \ \ -\ set\ *LOAD-COMPILING*\ to\ T\n=
+
+#: spvw.d:1691
+!\ -norc\ \ \ \ \ \ \ -\ do\ not\ load\ the\ user\ ~/.clisprc\ file\n=
+
+#: spvw.d:1692
+!\ -i\ file\ \ \ \ \ -\ load\ initfile\ (can\ be\ repeated)\n=
+
+#: spvw.d:1693
+!Actions\:\n=
+
+#: spvw.d:1694
+!\ -c\ [-l]\ lispfile\ [-o\ outputfile]\ -\ compile\ LISPFILE\n=
+
+#: spvw.d:1695
+!\ -x\ expression\ -\ execute\ the\ expression,\ then\ exit\n=
+
+#: spvw.d:1696
+!\ lispfile\ [argument\ ...]\ -\ load\ lispfile,\ then\ exit\n=
+
+#: spvw.d:1697
+!Default\ action\ is\ an\ interactive\ read-eval-print\ loop.\n=
+
+#: spvw.d:1755
+!\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Amiga\ version\:\ Joerg\ Hoehle\n=
+
+#: spvw.d:1759
+!\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ RISCOS\ port\:\ Peter\ Burwood,\ Bruno\ Haible\n=
+
+#: spvw.d:1970
+!Syntax\ for\ %s\:\ nnnnnnn\ or\ nnnnKB\ or\ nMB\n=
+
+#: spvw.d:1974
+!%s\ out\ of\ range\n=
+
+#: spvw.d:1986
+!memory\ size=
+
+#: spvw.d:1996
+!stack\ size=
+
+#: spvw.d:2317
+!Return\ value\ of\ malloc()\ \=\ %x\ is\ not\ compatible\ with\ type\ code\ distribution.\n=
+
+#: spvw.d:2324
+!Only\ %d\ bytes\ available.\n=
+
+#: spvw.d:2558
+!Couldn't\ determine\ the\ end\ of\ the\ SP\ stack\!\n=
+
+#: spvw.d:2779
+!\nWARNING\:\ No\ initialisation\ file\ specified.\n=
+
+#: spvw.d:2783 spvw.d:2798
+!Please\ try\:\ =
+
+#: spvw.d:2797
+!\nWARNING\:\ No\ installation\ directory\ specified.\n=
+
+#: spvw.d:3002
+!Not\ enough\ memory\ for\ Lisp.\n=
+
+#: spvw_alloca.d:49
+!\n***\ -\ Virtual\ memory\ exhausted.\ RESET=
+
+#: spvw_alloca.d:51
+!\n***\ -\ Memory\ exhausted.\ RESET=
+
+#: spvw_mmap.d:67 spvw_mmap.d:219 spvw_mmap.d:396 spvw_multimap.d:174
+!Cannot\ map\ memory\ to\ address\ 0x%x\ .=
+
+#: spvw_mmap.d:188
+!Cannot\ reserve\ address\ range\ at\ 0x%x\ .=
+
+#: spvw_mmap.d:199
+!Cannot\ reserve\ address\ range\ 0x%x-0x%x\ .=
+
+#: spvw_mmap.d:252
+!CreateFileMapping()\ failed.=
+
+#: spvw_mmap.d:259
+!MapViewOfFileEx(addr\=0x%x,off\=0x%x)\ failed.=
+
+#: spvw_mmap.d:266
+!MapViewOfFileEx()\ returned\ 0x%x\ instead\ of\ 0x%x.\n=
+
+#: spvw_mmap.d:283
+!VirtualFree()\ failed.=
+
+#: spvw_mmap.d:299
+!VirtualProtect()\ failed.=
+
+#: spvw_mmap.d:371 spvw_multimap.d:115
+!Cannot\ open\ /dev/zero\ .=
+
+#: spvw_multimap.d:144
+!msync(0x%x,0x%x,MS_INVALIDATE)\ fails.=
+
+#: spvw_multimap.d:209
+!Cannot\ open\ %s\ .=
+
+#: spvw_multimap.d:220
+!Cannot\ delete\ %s\ .=
+
+#: spvw_multimap.d:235
+!**\ WARNING\:\ **\ Too\ few\ free\ disk\ space\ for\ %s\ .\n=
+
+#: spvw_multimap.d:238
+!Please\ restart\ LISP\ with\ fewer\ memory\ (option\ -m).\n=
+
+#: spvw_multimap.d:246
+!Cannot\ make\ %s\ long\ enough.=
+
+#: spvw_multimap.d:265
+!Cannot\ fill\ %s\ .=
+
+#: spvw_multimap.d:282
+!Cannot\ close\ %s\ .=
+
+#: spvw_multimap.d:317
+!Cannot\ close\ /dev/zero\ .=
+
+#: spvw_multimap.d:353
+!Recompile\ your\ operating\ system\ with\ SYSV\ IPC\ support.\n=
+
+#: spvw_multimap.d:367
+!Cannot\ allocate\ private\ shared\ memory\ segment.=
+
+#: spvw_multimap.d:389
+!Cannot\ map\ shared\ memory\ to\ address\ 0x%x.=
+
+#: spvw_multimap.d:412
+!Cannot\ fill\ shared\ memory.=
+
+#: spvw_multimap.d:418
+!Could\ not\ fill\ shared\ memory.=
+
+#: spvw_multimap.d:433
+!Cannot\ remove\ shared\ memory\ segment.=
+
+#: spvw_fault.d:482
+!mprotect()\ fails.=
+
+#: spvw_sigsegv.d:31
+!\nSIGSEGV\ cannot\ be\ cured.\ Fault\ address\ \=\ 0x%x.\n=
+
+#: spvw_sigsegv.d:73
+!Apollo\ 13\ scenario\:\ Stack\ overflow\ handling\ failed.\ On\ the\ next\ stack\ overflow\ we\ will\ crash\!\!\!\n=
+
+#: spvw_sigint.d:76 spvw_sigint.d:157
+!Ctrl-C\:\ User\ break=
+
+#: spvw_garcol.d:2020
+!munmap()\ fails.=
+
+#: spvw_allocate.d:34
+!No\ more\ room\ for\ LISP\ objects=
+
+#: spvw_allocate.d:54
+!\n***\ -\ No\ more\ room\ for\ LISP\ objects\:\ RESET=
+
+#: spvw_allocate.d:272 spvw_allocate.d:337 spvw_allocate.d:418
+!Trying\ to\ make\ room\ through\ a\ GC...\n=
+
+#: spvw_memfile.d:235
+!disk\ full=
+
+#: spvw_memfile.d:763
+!operating\ system\ error\ during\ load\ of\ initialisation\ file\ `%s'\n=
+
+#: spvw_memfile.d:1235
+!Cannot\ map\ the\ initialisation\ file\ into\ memory.=
+
+#: spvw_memfile.d:1514
+!operating\ system\ error\ during\ load\ of\ initialisation\ file\n=
+
+#: spvw_memfile.d:1520
+!initialisation\ file\ was\ not\ created\ by\ this\ version\ of\ LISP\n=
+
+#: spvw_memfile.d:1524
+!not\ enough\ memory\ for\ initialisation\n=
+
+#: eval.d:553
+!~\:\ ~\ is\ a\ constant,\ cannot\ be\ bound\ dynamically=
+
+#: eval.d:1518 control.d:2517
+!Too\ many\ documentation\ strings\ in\ ~=
+
+#: eval.d:1730
+!FUNCTION\:\ lambda-list\ for\ ~\ is\ missing=
+
+#: eval.d:1740
+!FUNCTION\:\ lambda-list\ for\ ~\ should\ be\ a\ list,\ not\ ~=
+
+#: eval.d:1853
+!FUNCTION\:\ illegal\ declaration\ ~=
+
+#: eval.d:1864
+!FUNCTION\:\ ~\ is\ not\ a\ symbol,\ cannot\ be\ declared\ SPECIAL=
+
+#: eval.d:1947
+!FUNCTION\:\ too\ long\ variable\ specification\ after\ &OPTIONAL\:\ ~=
+
+#: eval.d:1988
+!FUNCTION\:\ &REST\ var\ must\ be\ followed\ by\ &KEY\ or\ &AUX\ or\ end\ of\ list\:\ ~=
+
+#: eval.d:1993
+!FUNCTION\:\ &REST\ must\ be\ followed\ by\ a\ variable\:\ ~=
+
+#: eval.d:2044
+!FUNCTION\:\ ~\ in\ ~\ is\ not\ a\ symbol=
+
+#: eval.d:2100
+!FUNCTION\:\ incorrect\ variable\ specification\ after\ &KEY\:\ ~=
+
+#: eval.d:2107
+!FUNCTION\:\ &ALLOW-OTHER-KEYS\ must\ be\ followed\ by\ &AUX\ or\ end\ of\ list\:\ ~=
+
+#: eval.d:2142
+!FUNCTION\:\ too\ long\ variable\ specification\ after\ &AUX\:\ ~=
+
+#: eval.d:2165
+!FUNCTION\:\ badly\ placed\ lambda-list\ keyword\ ~\:\ ~=
+
+#: eval.d:2170
+!FUNCTION\:\ ~\ is\ not\ a\ symbol,\ may\ not\ be\ used\ as\ a\ variable=
+
+#: eval.d:2175
+!FUNCTION\:\ ~\ is\ a\ constant,\ may\ not\ be\ used\ as\ a\ variable=
+
+#: eval.d:2182
+!FUNCTION\:\ too\ many\ parameters\ in\ the\ lambda-list\ ~=
+
+#: eval.d:2189
+!FUNCTION\:\ a\ dot\ in\ a\ lambda-list\ is\ allowed\ only\ for\ macros,\ not\ here\:\ ~=
+
+#: eval.d:2269
+!~\:\ ~\ is\ a\ special\ operator,\ not\ a\ function=
+
+#: eval.d:2286 symbol.d:31
+!~\:\ ~\ is\ a\ macro,\ not\ a\ function=
+
+#: eval.d:2303
+!~\:\ the\ function\ ~\ is\ undefined=
+
+#: eval.d:2350 sequence.d:1244 error.d:953
+!~\:\ ~\ is\ not\ a\ function=
+
+#: eval.d:2411
+!EVAL/APPLY\:\ keyword\ arguments\ for\ ~\ should\ occur\ pairwise=
+
+#: eval.d:2424 eval.d:2741
+!EVAL/APPLY\:\ too\ many\ arguments\ given\ to\ ~=
+
+#: eval.d:2439
+!EVAL/APPLY\:\ ~\ is\ not\ a\ symbol=
+
+#: eval.d:2465
+!EVAL/APPLY\:\ keyword\ ~\ is\ illegal\ for\ ~.\ The\ possible\ keywords\ are\ ~=
+
+#: eval.d:2659
+!EVAL/APPLY\:\ too\ few\ arguments\ given\ to\ ~=
+
+#: eval.d:3153
+!EVAL\:\ variable\ ~\ has\ no\ value=
+
+#: eval.d:3253 eval.d:4282 eval.d:5214 control.d:109
+!~\:\ ~\ is\ not\ a\ function\ name=
+
+#: eval.d:3332
+!EVAL\:\ too\ few\ parameters\ for\ special-form\ ~\:\ ~=
+
+#: eval.d:3346
+!EVAL\:\ too\ many\ parameters\ for\ special-form\ ~\:\ ~=
+
+#: eval.d:3359
+!EVAL\:\ dotted\ parameter\ list\ for\ special\ form\ ~\:\ ~=
+
+#: eval.d:3426
+!EVAL\:\ too\ few\ arguments\ given\ to\ ~\:\ ~=
+
+#: eval.d:3439
+!EVAL\:\ too\ many\ arguments\ given\ to\ ~\:\ ~=
+
+#: eval.d:3452
+!EVAL\:\ argument\ list\ given\ to\ ~\ is\ dotted\:\ ~=
+
+#: eval.d:4295
+!APPLY\:\ argument\ list\ given\ to\ ~\ is\ dotted=
+
+#: eval.d:4307
+!APPLY\:\ too\ many\ arguments\ given\ to\ ~=
+
+#: eval.d:4319
+!APPLY\:\ too\ few\ arguments\ given\ to\ ~=
+
+#: eval.d:6782 eval.d:6798
+!symbol\ ~\ has\ no\ value=
+
+#: eval.d:6813
+!assignment\ to\ constant\ symbol\ ~\ is\ impossible=
+
+#: eval.d:7439 control.d:2415
+!~\:\ too\ many\ arguments\ given\ to\ ~=
+
+#: eval.d:7617 eval.d:7654
+!(~\ ~)\:\ the\ tagbody\ of\ the\ tags\ ~\ has\ already\ been\ left=
+
+#: eval.d:7718 control.d:2108
+!~\:\ there\ is\ no\ CATCHer\ for\ tag\ ~=
+
+#: eval.d:7743
+!STACK\ corrupted=
+
+#: eval.d:8127
+!~\:\ ~\ is\ not\ a\ correct\ index\ into\ ~=
+
+#: eval.d:8739
+!undefined\ bytecode\ in\ ~\ at\ byte\ ~=
+
+#: eval.d:8749
+!too\ many\ return\ values=
+
+#: eval.d:8756
+!Corrupted\ STACK\ in\ ~\ at\ byte\ ~=
+
+#: control.d:63
+!~\:\ function\ name\ ~\ should\ be\ a\ symbol=
+
+#: control.d:91
+!~\:\ undefined\ function\ ~=
+
+#: control.d:129
+!~\:\ ~\ has\ no\ dynamic\ value=
+
+#: control.d:175 symbol.d:23
+!~\:\ ~\ has\ no\ global\ function\ definition=
+
+#: control.d:261
+!~\:\ the\ value\ of\ the\ constant\ ~\ may\ not\ be\ altered=
+
+#: control.d:289
+!~\ called\ with\ odd\ number\ of\ arguments\:\ ~=
+
+#: control.d:299
+!dotted\ list\ given\ to\ ~\ \:\ ~=
+
+#: control.d:399
+!~\:\ the\ value\ of\ the\ constant\ ~\ must\ not\ be\ removed=
+
+#: control.d:424
+!~\:\ the\ special\ operator\ definition\ of\ ~\ must\ not\ be\ removed=
+
+#: control.d:506
+!~\:\ doc-strings\ are\ not\ allowed\ here\:\ ~=
+
+#: control.d:579
+!~\:\ ~\ is\ not\ a\ symbol,\ but\ was\ declared\ SPECIAL=
+
+#: control.d:622 control.d:893
+!~\:\ illegal\ variable\ specification\ ~=
+
+#: control.d:661
+!~\:\ symbol\ ~\ is\ declared\ special\ and\ must\ not\ be\ declared\ a\ macro=
+
+#: control.d:668
+!~\:\ symbol\ ~\ must\ not\ be\ declared\ SPECIAL\ and\ a\ macro\ at\ the\ same\ time=
+
+#: control.d:677 control.d:906
+!~\:\ ~\ is\ a\ constant,\ cannot\ be\ bound=
+
+#: control.d:697
+!~\:\ too\ many\ variables\ and/or\ declarations=
+
+#: control.d:981
+!~\:\ ~\ is\ not\ a\ function\ specification=
+
+#: control.d:1146
+!~\:\ ~\ is\ not\ a\ macro\ specification=
+
+#: control.d:1154
+!~\:\ macro\ name\ ~\ should\ be\ a\ symbol=
+
+#: control.d:1192
+!~\:\ ~\ is\ not\ a\ function\ and\ macro\ specification=
+
+#: control.d:1200
+!~\:\ function\ and\ macro\ name\ ~\ should\ be\ a\ symbol=
+
+#: control.d:1327
+!~\:\ clause\ ~\ should\ be\ a\ list=
+
+#: control.d:1360
+!~\:\ missing\ key\ list\:\ ~=
+
+#: control.d:1370
+!~\:\ the\ ~\ clause\ must\ be\ the\ last\ one=
+
+#: control.d:1434
+!~\:\ the\ block\ named\ ~\ has\ already\ been\ left=
+
+#: control.d:1473
+!~\:\ no\ block\ named\ ~\ is\ currently\ visible=
+
+#: control.d:1722
+!~\:\ ~\ is\ neither\ tag\ nor\ form=
+
+#: control.d:1768
+!~\:\ illegal\ tag\ ~=
+
+#: control.d:1807
+!~\:\ tagbody\ for\ tag\ ~\ has\ already\ been\ left=
+
+#: control.d:1822
+!~\:\ no\ tag\ named\ ~\ is\ currently\ visible=
+
+#: control.d:1841
+!~\:\ too\ many\ values=
+
+#: control.d:1886
+!~\:\ too\ many\ arguments\ to\ ~=
+
+#: control.d:2149
+!Argument\ ~\ is\ not\ a\ macroexpansion\ environment=
+
+#: control.d:2211
+!declarations\ ~\ are\ not\ allowed\ here=
+
+#: control.d:2233
+!~\:\ ~\ evaluated\ to\ the\ values\ ~,\ not\ of\ type\ ~=
+
+#: control.d:2249
+!~\:\ bad\ declaration\ ~=
+
+#: control.d:2362
+!~\:\ ~\ may\ not\ be\ used\ as\ an\ environment=
+
+#: control.d:2510
+!no\ doc-strings\ allowed\ here\:\ ~=
+
+#: control.d:2575
+!keyword\ argument\ list\ ~\ has\ an\ odd\ length=
+
+#: control.d:2611
+!illegal\ keyword/value\ pair\ ~,\ ~\ in\ argument\ list.\ The\ allowed\ keywords\ are\ ~=
+
+#: encoding.d:47
+!Character\ \#\\u$$$$\ cannot\ be\ represented\ in\ the\ character\ set\ ~=
+
+#: encoding.d:226
+!character\ \#x$$$$$$$$\ in\ ~\ conversion,\ not\ a\ Unicode-16,\ sorry=
+
+#: encoding.d:420
+!invalid\ byte\ \#x$$\ in\ ~\ conversion,\ not\ a\ Unicode-16=
+
+#: encoding.d:438
+!invalid\ byte\ sequence\ \#x$$\ \#x$$\ in\ ~\ conversion=
+
+#: encoding.d:459
+!invalid\ byte\ sequence\ \#x$$\ \#x$$\ \#x$$\ in\ ~\ conversion=
+
+#: encoding.d:1064
+!invalid\ byte\ \#x$$\ in\ ~\ conversion=
+
+#: encoding.d:1446
+!~\:\ illegal\ \:CHARSET\ argument\ ~=
+
+#: encoding.d:1459
+!~\:\ illegal\ \:LINE-TERMINATOR\ argument\ ~=
+
+#: encoding.d:1471
+!~\:\ illegal\ \:INPUT-ERROR-ACTION\ argument\ ~=
+
+#: encoding.d:1483
+!~\:\ illegal\ \:OUTPUT-ERROR-ACTION\ argument\ ~=
+
+#: encoding.d:1532
+!~\:\ argument\ ~\ is\ not\ a\ character\ set=
+
+#: encoding.d:2195
+!~\:\ ~\ is\ not\ a\ 1\:1\ encoding=
+
+#: pathname.d:1209 pathname.d:1260
+!~\:\ host\ should\ be\ NIL\ or\ a\ string,\ not\ ~=
+
+#: pathname.d:1231 pathname.d:1280
+!~\:\ illegal\ hostname\ ~=
+
+#: pathname.d:1302
+!~\:\ host\ should\ be\ NIL,\ not\ ~=
+
+#: pathname.d:1421
+!~\:\ argument\ should\ be\ a\ string,\ symbol,\ file\ stream\ or\ pathname,\ not\ ~=
+
+#: pathname.d:1464
+!~\:\ filename\ for\ ~\ is\ unknown=
+
+#: pathname.d:1884
+!~(~\ ~\ ~)\:\ a\ logical\ pathname\ must\ contain\ host=
+
+#: pathname.d:2028 pathname.d:2392
+!~\:\ there\ is\ no\ environment\ variable\ ~=
+
+#: pathname.d:2335
+!~\:\ there\ is\ no\ user\ named\ ~=
+
+#: pathname.d:2642
+!~\:\ syntax\ error\ in\ filename\ ~\ at\ position\ ~=
+
+#: pathname.d:2659 pathname.d:2674
+!~\:\ hosts\ ~\ and\ ~\ of\ ~\ should\ coincide=
+
+#: pathname.d:2916
+!~\:\ argument\ ~\ is\ not\ a\ logical\ pathname,\ string,\ stream\ or\ symbol=
+
+#: pathname.d:2972
+!~\:\ endless\ loop\ while\ resolving\ ~=
+
+#: pathname.d:2994
+!~\:\ unknown\ logical\ host\ ~\ in\ ~=
+
+#: pathname.d:3006
+!~\:\ No\ replacement\ rule\ for\ ~\ is\ known.=
+
+#: pathname.d:3400
+!~\:\ \:VERSION-argument\ should\ be\ NIL\ or\ a\ positive\ fixnum\ or\ \:WILD\ or\ \:NEWEST,\ not\ ~=
+
+#: pathname.d:3427
+!~\:\ \:VERSION-argument\ should\ be\ NIL\ or\ \:WILD\ or\ \:NEWEST,\ not\ ~=
+
+#: pathname.d:4270
+!~\:\ on\ host\ ~,\ device\ ~\ is\ invalid,\ should\ be\ NIL=
+
+#: pathname.d:4520
+!~\:\ illegal\ ~\ argument\ ~=
+
+#: pathname.d:4866
+!wildcards\ are\ not\ allowed\ here\:\ ~=
+
+#: pathname.d:4903
+!~\:\ argument\ ~\ should\ be\ ~,\ ~,\ ~,\ ~,\ ~,\ ~\ or\ ~=
+
+#: pathname.d:6075
+!~\:\ replacement\ pieces\ ~\ do\ not\ fit\ into\ ~=
+
+#: pathname.d:6168
+!~\:\ ~\ is\ not\ a\ specialization\ of\ ~=
+
+#: pathname.d:6219
+!(~\ ~\ ~\ ~)\ is\ ambiguous\:\ ~=
+
+#: pathname.d:6245
+!nonexistent\ directory\:\ ~=
+
+#: pathname.d:6261
+!~\:\ File\ ~\ already\ exists=
+
+#: pathname.d:6539 pathname.d:7395
+!no\ directory\ ~\ above\ ~=
+
+#: pathname.d:6547
+!"..\\\\"\ after\ "...\\\\"\ is\ invalid\:\ ~=
+
+#: pathname.d:6752
+!Couldn't\ access\ current\ directory=
+
+#: pathname.d:6902
+!~\:\ ~\ names\ a\ file,\ not\ a\ directory=
+
+#: pathname.d:6950 pathname.d:7147 pathname.d:7514
+!~\:\ ~\ names\ a\ directory,\ not\ a\ file=
+
+#: pathname.d:6996
+!UNIX\ error\ while\ GETWD\:\ ~=
+
+#: pathname.d:7005
+!UNIX\ GETWD\ returned\ ~=
+
+#: pathname.d:7107
+!UNIX\ REALPATH\ returned\ ~=
+
+#: pathname.d:7329
+!~\:\ If\ a\ device\ is\ specified,\ the\ directory\ must\ begin\ with\ ~\:\ ~=
+
+#: pathname.d:7721
+!no\ file\ name\ given\:\ ~=
+
+#: pathname.d:7735
+!not\ a\ directory\:\ ~=
+
+#: pathname.d:7804
+!~\:\ file\ ~\ does\ not\ exist=
+
+#: pathname.d:7833
+!~\:\ pathname\ with\ type\ but\ without\ name\ makes\ no\ sense\:\ ~=
+
+#: pathname.d:8064
+!cannot\ delete\ file\ ~\ since\ there\ is\ file\ stream\ open\ to\ it=
+
+#: pathname.d:8126
+!cannot\ rename\ file\ ~\ since\ there\ is\ file\ stream\ open\ to\ it=
+
+#: pathname.d:8720
+!file\ ~\ does\ not\ exist=
+
+#: pathname.d:8726
+!a\ file\ named\ ~\ already\ exists=
+
+#: pathname.d:8788
+!~\:\ illegal\ \:DIRECTION\ argument\ ~=
+
+#: pathname.d:8817
+!~\:\ illegal\ \:IF-EXISTS\ argument\ ~=
+
+#: pathname.d:8837
+!~\:\ illegal\ \:IF-DOES-NOT-EXIST\ argument\ ~=
+
+#: pathname.d:10035
+!~\:\ cannot\ change\ default\ directory\ on\ remote\ host\:\ ~=
+
+#: pathname.d:10081
+!root\ directory\ not\ allowed\ here\:\ ~=
+
+#: pathname.d:10753 pathname.d:10800 pathname.d:10860
+!~\:\ the\ command\ should\ be\ a\ string,\ not\ ~=
+
+#: pathname.d:11119
+!~\:\ library\ directory\ is\ not\ known,\ use\ a\ command\ line\ option\ to\ specify\ it=
+
+#: stream.d:223 stream.d:16250
+!~\ on\ ~\ is\ illegal=
+
+#: stream.d:509 stream.d:720
+!Return\ value\ ~\ of\ call\ to\ ~\ should\ be\ an\ integer\ between\ ~\ and\ ~.=
+
+#: stream.d:619
+!~\:\ the\ last\ character\ read\ from\ ~\ was\ not\ ~=
+
+#: stream.d:627
+!~\ from\ ~\ without\ ~\ before\ it=
+
+#: stream.d:897
+!~\:\ cannot\ output\ to\ ~=
+
+#: stream.d:913
+!~\ is\ not\ a\ character,\ cannot\ be\ output\ onto\ ~=
+
+#: stream.d:929
+!~\ is\ not\ an\ integer,\ cannot\ be\ output\ onto\ ~=
+
+#: stream.d:944
+!integer\ ~\ is\ out\ of\ range,\ cannot\ be\ output\ onto\ ~=
+
+#: stream.d:997
+!~\:\ argument\ ~\ should\ be\ an\ input\ stream=
+
+#: stream.d:1015
+!~\:\ argument\ ~\ should\ be\ an\ output\ stream=
+
+#: stream.d:1354
+!~\:\ argument\ should\ be\ a\ symbol,\ not\ ~=
+
+#: stream.d:2397 stream.d:2890
+!~\ is\ beyond\ the\ end\ because\ the\ string\ ~\ has\ been\ adjusted=
+
+#: stream.d:2528
+!~\:\ ~\ is\ not\ a\ string\ input\ stream=
+
+#: stream.d:2621 charstrg.d:3322
+!~\:\ ~\ argument\ must\ be\ a\ subtype\ of\ ~,\ not\ ~=
+
+#: stream.d:2658
+!~\:\ ~\ is\ not\ a\ string\ output\ stream=
+
+#: stream.d:2700
+!~\:\ argument\ ~\ should\ be\ a\ string\ with\ fill\ pointer=
+
+#: stream.d:3002
+!~\:\ ~\ is\ not\ a\ buffered\ input\ stream=
+
+#: stream.d:3329
+!~\:\ stream\ must\ be\ a\ generic-stream,\ not\ ~=
+
+#: stream.d:3421
+!~\:\ illegal\ \:BUFFERED\ argument\ ~=
+
+#: stream.d:3537 stream.d:18402
+!~\:\ illegal\ \:ELEMENT-TYPE\ argument\ ~=
+
+#: stream.d:3611
+!~\:\ illegal\ \:EXTERNAL-FORMAT\ argument\ ~=
+
+#: stream.d:4052
+!~\:\ Ctrl-C\:\ User\ break=
+
+#: stream.d:4104
+!unknown\ character\ set\ ~=
+
+#: stream.d:6397
+!Unbuffered\ streams\ need\ an\ ~\ with\ a\ bit\ size\ being\ a\ multiple\ of\ 8,\ not\ ~=
+
+#: stream.d:6789
+!Closed\ ~\ because\ disk\ is\ full.=
+
+#: stream.d:6977
+!cannot\ position\ ~\ beyond\ EOF=
+
+#: stream.d:8604
+!~\:\ argument\ ~\ ~\ was\ specified,\ but\ ~\ is\ not\ a\ regular\ file.=
+
+#: stream.d:8639
+!~\:\ arguments\ ~\ ~\ and\ ~\ ~\ were\ specified,\ but\ ~\ is\ not\ a\ regular\ file.=
+
+#: stream.d:8701
+!file\ ~\ is\ not\ an\ integer\ file=
+
+#: stream.d:10276 stream.d:17796
+!Return\ value\ ~\ of\ call\ to\ ~\ is\ not\ a\ ~.=
+
+#: stream.d:10299
+!Return\ value\ ~\ of\ call\ to\ ~\ contains\ ~\ which\ is\ not\ a\ ~.=
+
+#: stream.d:10618
+!character\ ~\ contains\ bits,\ cannot\ be\ output\ onto\ ~=
+
+#: stream.d:11357
+!RAW\ mode\ not\ supported\ on\ ~=
+
+#: stream.d:11789
+!~\:\ argument\ ~\ should\ be\ a\ window\ stream=
+
+#: stream.d:12444
+!cannot\ output\ to\ standard\ output=
+
+#: stream.d:13840
+!environment\ has\ no\ TERM\ variable=
+
+#: stream.d:13845
+!terminal\ type\ ~\ unknown\ to\ termcap=
+
+#: stream.d:13870
+!insufficient\ terminal\:\ hardcopy\ terminal=
+
+#: stream.d:13874
+!insufficient\ terminal\:\ overstrikes,\ cannot\ clear\ output=
+
+#: stream.d:13878
+!insufficient\ terminal\:\ cannot\ scroll=
+
+#: stream.d:13883
+!insufficient\ terminal\:\ cannot\ clear\ screen=
+
+#: stream.d:13887
+!insufficient\ terminal\:\ cannot\ position\ cursor\ randomly=
+
+#: stream.d:14399
+!~\:\ package\ SCREEN\ is\ not\ implemented=
+
+#: stream.d:15928
+!host\ should\ be\ string,\ not\ ~=
+
+#: stream.d:15936
+!display\ should\ be\ a\ nonnegative\ fixnum,\ not\ ~=
+
+#: stream.d:16004
+!~\:\ stream\ must\ be\ a\ socket-stream,\ not\ ~=
+
+#: stream.d:16017
+!~\:\ argument\ ~\ should\ be\ a\ vector\ of\ type\ (ARRAY\ (UNSIGNED-BYTE\ 8)\ (*))=
+
+#: stream.d:16041 stream.d:18444 stream.d:18518 stream.d:18736 stream.d:18816
+#: io.d:1042
+!~\:\ input\ stream\ ~\ has\ reached\ its\ end=
+
+#: stream.d:16243
+!~\:\ ~\ is\ not\ a\ SOCKET-SERVER=
+
+#: stream.d:16309
+!~\:\ argument\ ~\ is\ neither\ an\ open\ SOCKET-STREAM\ nor\ a\ positive\ FIXNUM=
+
+#: stream.d:16503
+!~\:\ argument\ ~\ is\ not\ an\ open\ SOCKET-STREAM=
+
+#: stream.d:16516
+!~\:\ argument\ ~\ is\ not\ a\ SOCKET-STREAM=
+
+#: stream.d:16562
+!~\:\ list\ ~\ is\ too\ long\ (~\ maximum)=
+
+#: stream.d:16834
+!The\ value\ of\ ~\ is\ not\ a\ stream\:\ ~=
+
+#: stream.d:16838
+!The\ value\ of\ ~\ is\ not\ an\ appropriate\ stream\:\ ~=
+
+#: stream.d:16852
+!The\ value\ of\ ~\ was\ not\ a\ stream\:\ ~.\ It\ has\ been\ changed\ to\ ~.=
+
+#: stream.d:16871
+!readline\ library\:\ out\ of\ memory.=
+
+#: stream.d:17175
+!~\:\ The\ ~\ of\ ~\ cannot\ be\ changed\ from\ ~\ to\ ~.=
+
+#: stream.d:18342
+!Return\ value\ ~\ of\ call\ to\ ~\ is\ not\ a\ fixnum\ >\=\ 0\ or\ NIL.=
+
+#: stream.d:18361
+!~\ needs\ an\ ~\ with\ a\ bit\ size\ being\ a\ multiple\ of\ 8,\ not\ ~=
+
+#: stream.d:18423
+!~\:\ illegal\ endianness\ argument\ ~=
+
+#: stream.d:19059 stream.d:19071
+!~\ is\ not\ a\ ~,\ cannot\ be\ output\ onto\ ~=
+
+#: stream.d:19158
+!~\:\ argument\ ~\ is\ not\ an\ open\ file\ stream=
+
+#: stream.d:19192
+!~\:\ position\ argument\ should\ be\ ~\ or\ ~\ or\ a\ nonnegative\ integer,\ not\ ~=
+
+#: socket.d:1010
+!~\:\ ~=
+
+#: io.d:484
+!The\ value\ of\ ~\ was\ not\ a\ readtable.\ It\ has\ been\ reset.=
+
+#: io.d:570
+!~\:\ argument\ ~\ is\ not\ a\ readtable=
+
+#: io.d:773
+!~\:\ ~\ is\ a\ dispatch\ macro\ character=
+
+#: io.d:838
+!~\:\ ~\ is\ not\ a\ dispatch\ macro\ character=
+
+#: io.d:867
+!~\:\ digit\ $\ not\ allowed\ as\ sub-char=
+
+#: io.d:917
+!~\:\ new\ value\ ~\ should\ be\ ~,\ ~,\ ~\ or\ ~.=
+
+#: io.d:954
+!The\ value\ of\ ~\ should\ be\ an\ integer\ between\ 2\ and\ 36,\ not\ ~.\nIt\ has\ been\ reset\ to\ 10.=
+
+#: io.d:1005
+!~\ from\ ~\:\ character\ read\ should\ be\ a\ character\:\ ~=
+
+#: io.d:1059
+!~\:\ input\ stream\ ~\ ends\ within\ an\ object.\ Last\ opening\ parenthesis\ probably\ in\ line\ ~.=
+
+#: io.d:1065
+!~\:\ input\ stream\ ~\ ends\ within\ an\ object=
+
+#: io.d:1374
+!~\ from\ ~\:\ illegal\ character\ ~=
+
+#: io.d:1387
+!~\:\ input\ stream\ ~\ ends\ within\ a\ token\ after\ single\ escape\ character=
+
+#: io.d:1435
+!~\:\ input\ stream\ ~\ ends\ within\ a\ token\ after\ multiple\ escape\ character=
+
+#: io.d:2017
+!~\ from\ ~\:\ ~\ has\ no\ macro\ character\ definition=
+
+#: io.d:2031
+!~\ from\ ~\:\ macro\ character\ definition\ for\ ~\ may\ not\ return\ ~\ values,\ only\ one\ value.=
+
+#: io.d:2055
+!~\:\ input\ stream\ ~\ ends\ within\ read\ macro\ beginning\ to\ ~=
+
+#: io.d:2089
+!~\ from\ ~\:\ After\ ~\ is\ ~\ an\ undefined\ dispatch\ macro\ character=
+
+#: io.d:2103
+!~\ from\ ~\:\ dispatch\ macro\ character\ definition\ for\ ~\ after\ ~\ may\ not\ return\ ~\ values,\ only\ one\ value.=
+
+#: io.d:2179
+!~\ from\ ~\:\ a\ token\ consisting\ only\ of\ dots\ cannot\ be\ meaningfully\ read\ in=
+
+#: io.d:2284
+!~\ from\ ~\:\ too\ many\ colons\ in\ token\ ~=
+
+#: io.d:2334
+!~\ from\ ~\:\ there\ is\ no\ package\ with\ name\ ~=
+
+#: io.d:2363
+!~\ from\ ~\:\ ~\ has\ no\ external\ symbol\ with\ name\ ~=
+
+#: io.d:2411
+!~\ from\ ~\:\ token\ "."\ not\ allowed\ here=
+
+#: io.d:2465 io.d:6624
+!~\:\ the\ value\ of\ ~\ has\ been\ arbitrarily\ altered=
+
+#: io.d:2481
+!~\:\ no\ entry\ for\ ~\ from\ ~\ in\ ~\ \=\ ~=
+
+#: io.d:2692
+!~\ from\ ~\:\ illegal\ end\ of\ dotted\ list=
+
+#: io.d:2768
+!~\ from\ ~\:\ an\ object\ cannot\ start\ with\ ~=
+
+#: io.d:2859
+!~\:\ input\ stream\ ~\ ends\ within\ a\ string=
+
+#: io.d:2925
+!~\ from\ ~\:\ no\ number\ allowed\ between\ \#\ and\ $=
+
+#: io.d:3024
+!~\:\ input\ stream\ ~\ ends\ within\ a\ comment\ \#$\ ...\ $\#=
+
+#: io.d:3106
+!~\ from\ ~\:\ font\ number\ ~\ for\ character\ is\ too\ large,\ should\ be\ \=\ 0=
+
+#: io.d:3139
+!~\ from\ ~\:\ there\ is\ no\ character\ bit\ with\ name\ ~=
+
+#: io.d:3206
+!~\ from\ ~\:\ there\ is\ no\ character\ with\ name\ ~=
+
+#: io.d:3269
+!~\ from\ ~\:\ token\ ~\ after\ \#$\ is\ not\ a\ rational\ number\ in\ base\ ~=
+
+#: io.d:3348
+!~\ from\ ~\:\ the\ number\ base\ must\ be\ given\ between\ \#\ and\ R=
+
+#: io.d:3363
+!~\ from\ ~\:\ The\ base\ ~\ given\ between\ \#\ and\ R\ should\ lie\ between\ 2\ and\ 36=
+
+#: io.d:3411
+!~\ from\ ~\:\ bad\ syntax\ for\ complex\ number\:\ \#C~=
+
+#: io.d:3446
+!~\ from\ ~\:\ token\ expected\ after\ \#\:=
+
+#: io.d:3475
+!~\ from\ ~\:\ token\ ~\ after\ \#\:\ should\ contain\ no\ colon=
+
+#: io.d:3528
+!~\ from\ ~\:\ only\ zeroes\ and\ ones\ are\ allowed\ after\ \#*=
+
+#: io.d:3557
+!~\ from\ ~\:\ bit\ vector\ is\ longer\ than\ the\ explicitly\ given\ length\ ~=
+
+#: io.d:3566
+!~\ from\ ~\:\ must\ specify\ element\ of\ bit\ vector\ of\ length\ ~=
+
+#: io.d:3646
+!~\ from\ ~\:\ vector\ is\ longer\ than\ the\ explicitly\ given\ length\ ~=
+
+#: io.d:3655
+!~\ from\ ~\:\ must\ specify\ element\ of\ vector\ of\ length\ ~=
+
+#: io.d:3740
+!~\ from\ ~\:\ bad\ syntax\ for\ array\:\ \#A~=
+
+#: io.d:3806
+!~\ from\ ~\:\ ~\ \=\ ~\ doesn't\ allow\ the\ evaluation\ of\ ~=
+
+#: io.d:3933
+!~\ from\ ~\:\ a\ number\ must\ be\ given\ between\ \#\ and\ $=
+
+#: io.d:3945
+!~\ from\ ~\:\ label\ \#~?\ too\ large=
+
+#: io.d:3967
+!~\ from\ ~\:\ the\ value\ of\ ~\ has\ been\ altered\ arbitrarily,\ it\ is\ not\ an\ alist\:\ ~=
+
+#: io.d:3987
+!~\ from\ ~\:\ label\ \#~\=\ may\ not\ be\ defined\ twice=
+
+#: io.d:4014
+!~\ from\ ~\:\ \#~\=\ \#~\#\ is\ illegal=
+
+#: io.d:4042
+!~\ from\ ~\:\ undefined\ label\ \#~\#=
+
+#: io.d:4059
+!~\ from\ ~\:\ objects\ printed\ as\ \#<...>\ cannot\ be\ read\ back\ in=
+
+#: io.d:4077
+!~\ from\ ~\:\ objects\ printed\ as\ \#\ in\ view\ of\ ~\ cannot\ be\ read\ back\ in=
+
+#: io.d:4159
+!~\ from\ ~\:\ illegal\ feature\ ~=
+
+#: io.d:4295
+!~\ from\ ~\:\ \#S\ must\ be\ followed\ by\ the\ type\ and\ the\ contents\ of\ the\ structure,\ not\ ~=
+
+#: io.d:4308
+!~\ from\ ~\:\ the\ type\ of\ a\ structure\ should\ be\ a\ symbol,\ not\ ~=
+
+#: io.d:4322
+!~\ from\ ~\:\ bad\ HASH-TABLE=
+
+#: io.d:4349
+!~\ from\ ~\:\ bad\ ~=
+
+#: io.d:4381
+!~\ from\ ~\:\ no\ structure\ of\ type\ ~\ has\ been\ defined=
+
+#: io.d:4392
+!~\ from\ ~\:\ bad\ ~\ for\ ~=
+
+#: io.d:4404
+!~\ from\ ~\:\ structures\ of\ type\ ~\ cannot\ be\ read\ in,\ missing\ constructor\ function=
+
+#: io.d:4426
+!~\ from\ ~\:\ a\ structure\ ~\ may\ not\ contain\ a\ component\ "."=
+
+#: io.d:4438
+!~\ from\ ~\:\ ~\ is\ not\ a\ symbol,\ not\ a\ slot\ name\ of\ structure\ ~=
+
+#: io.d:4448
+!~\ from\ ~\:\ missing\ value\ of\ slot\ ~\ in\ structure\ ~=
+
+#: io.d:4470
+!~\ from\ ~\:\ too\ many\ slots\ for\ structure\ ~=
+
+#: io.d:4517
+!~\ from\ ~\:\ illegal\ syntax\ of\ closure\ code\ vector\ after\ \#~Y=
+
+#: io.d:4572
+!~\ from\ ~\:\ object\ \#Y~\ has\ not\ the\ syntax\ of\ a\ compiled\ closure=
+
+#: io.d:4718
+!~\ from\ ~\:\ bad\ syntax\ for\ pathname\:\ \#P~=
+
+#: io.d:4937 io.d:10468
+!~\:\ ~\ is\ not\ a\ character=
+
+#: io.d:4983
+!~\:\ peek\ type\ should\ be\ NIL\ or\ T\ or\ a\ character,\ not\ ~=
+
+#: io.d:5144
+!~\:\ ~\ argument\ should\ be\ an\ integer\ between\ 2\ and\ 36,\ not\ ~=
+
+#: io.d:5245
+!~\:\ string\ ~\ does\ not\ have\ integer\ syntax=
+
+#: io.d:5417
+!~\:\ Despite\ of\ ~,\ ~\ cannot\ be\ printed\ readably.=
+
+#: io.d:5443
+!~\:\ the\ value\ ~\ of\ ~\ is\ neither\ ~\ nor\ ~\ nor\ ~.\nIt\ is\ reset\ to\ ~.=
+
+#: io.d:5886
+!~\:\ must\ be\ a\ positive\ integer\ or\ NIL,\ not\ ~=
+
+#: io.d:6847
+!~\:\ not\ enough\ stack\ space\ for\ carrying\ out\ circularity\ analysis=
+
+#: io.d:8571
+!~\:\ bad\ ~=
+
+#: io.d:8696 record.d:243
+!~\:\ ~\ is\ not\ a\ structure=
+
+#: io.d:9713
+!~\:\ an\ unknown\ record\ type\ has\ been\ generated\!=
+
+#: array.d:228
+!index\ too\ large=
+
+#: array.d:237
+!An\ array\ has\ been\ shortened\ by\ adjusting\ it\ while\ another\ array\ was\ displaced\ to\ it.=
+
+#: array.d:329
+!~\:\ ~\ is\ not\ an\ array=
+
+#: array.d:364 foreign.d:2282
+!~\:\ got\ ~\ subscripts,\ but\ ~\ has\ rank\ ~=
+
+#: array.d:382 foreign.d:2299
+!~\:\ subscripts\ ~\ for\ ~\ are\ not\ of\ type\ `(INTEGER\ 0\ (,ARRAY-DIMENSION-LIMIT))=
+
+#: array.d:411 foreign.d:2310
+!~\:\ subscripts\ ~\ for\ ~\ are\ out\ of\ range=
+
+#: array.d:474
+!~\:\ index\ ~\ for\ ~\ is\ not\ of\ type\ `(INTEGER\ 0\ (,ARRAY-DIMENSION-LIMIT))=
+
+#: array.d:495
+!~\:\ index\ ~\ for\ ~\ is\ out\ of\ range=
+
+#: array.d:598
+!~\:\ ~\ does\ not\ fit\ into\ ~,\ bad\ type=
+
+#: array.d:917
+!~\:\ ~\ is\ not\ an\ nonnegative\ integer\ less\ than\ the\ rank\ of\ ~=
+
+#: array.d:1128
+!~\:\ ~\ is\ not\ an\ array\ of\ bits=
+
+#: array.d:1993
+!~\:\ The\ arguments\ ~\ and\ ~\ should\ be\ arrays\ of\ bits\ with\ the\ same\ dimensions=
+
+#: array.d:2004
+!~\:\ The\ arguments\ ~,\ ~\ and\ ~\ should\ be\ arrays\ of\ bits\ with\ the\ same\ dimensions=
+
+#: array.d:3994
+!~\:\ vector\ ~\ has\ no\ fill\ pointer=
+
+#: array.d:4044
+!~\:\ ~\ has\ length\ zero=
+
+#: array.d:4072
+!~\ works\ only\ on\ adjustable\ arrays,\ not\ on\ ~=
+
+#: array.d:4090
+!~\:\ extension\ ~\ should\ be\ a\ positive\ fixnum=
+
+#: array.d:4114
+!~\:\ extending\ the\ vector\ by\ ~\ elements\ makes\ it\ too\ long=
+
+#: array.d:4186
+!~\:\ cannot\ push\ ~\ into\ array\ ~\ (bad\ type)=
+
+#: array.d:4485
+!~\:\ dimension\ ~\ is\ not\ of\ type\ `(INTEGER\ 0\ (,ARRAY-DIMENSION-LIMIT))=
+
+#: array.d:4528
+!~\:\ dimensions\ ~\ produce\ too\ large\ total-size=
+
+#: array.d:4570
+!~\:\ ambiguous,\ more\ than\ one\ initialisation\ specified=
+
+#: array.d:4582
+!~\:\ ~\ must\ not\ be\ specified\ without\ ~=
+
+#: array.d:4629
+!~\:\ the\ initial-element\ ~\ is\ not\ of\ type\ ~=
+
+#: array.d:4720
+!~\:\ ~\ is\ of\ incorrect\ length=
+
+#: array.d:4751
+!~\:\ ~-argument\ ~\ is\ not\ an\ array=
+
+#: array.d:4794
+!~\:\ ~-argument\ ~\ does\ not\ have\ element\ type\ ~=
+
+#: array.d:4811
+!~\:\ ~-argument\ ~\ is\ not\ of\ type\ `(INTEGER\ 0\ (,ARRAY-TOTAL-SIZE-LIMIT))=
+
+#: array.d:4823
+!~\:\ array-total-size\ +\ displaced-offset\ (\=\ ~)\ exceeds\ total\ size\ ~\ of\ ~-argument=
+
+#: array.d:4849
+!~\:\ fill-pointer\ ~\ should\ be\ a\ nonnegative\ fixnum=
+
+#: array.d:4858
+!~\:\ fill-pointer\ argument\ ~\ is\ larger\ than\ the\ length\ ~=
+
+#: array.d:4928
+!~\:\ attempted\ rank\ ~\ is\ too\ large=
+
+#: array.d:4942
+!~\:\ ~\ may\ not\ be\ specified\ for\ an\ array\ of\ rank\ ~=
+
+#: array.d:5141
+!~\:\ array\ ~\ is\ not\ adjustable=
+
+#: array.d:5164
+!~\:\ rank\ ~\ of\ array\ ~\ cannot\ be\ altered\:\ ~=
+
+#: array.d:5180
+!~\:\ array\ ~\ does\ not\ have\ element-type\ ~=
+
+#: array.d:5234
+!~\:\ cannot\ displace\ array\ ~\ to\ itself=
+
+#: array.d:5258
+!~\:\ array\ ~\ has\ no\ fill-pointer=
+
+#: array.d:5273
+!~\:\ the\ fill-pointer\ of\ array\ ~\ is\ ~,\ greater\ than\ ~=
+
+#: array.d:5424
+!Illegal\ START\ index\ ~\ for\ ~=
+
+#: array.d:5460
+!Illegal\ END\ index\ ~\ for\ ~=
+
+#: array.d:5474
+!~\:\ invalid\ bit-vector\ length\ ~=
+
+#: hashtabl.d:1148
+!Hash\ table\ size\ ~\ too\ large=
+
+#: hashtabl.d:1194
+!internal\ error\ occured\ while\ resizing\ ~=
+
+#: hashtabl.d:1305
+!~\:\ illegal\ \:TEST\ argument\ ~=
+
+#: hashtabl.d:1322
+!~\:\ \:SIZE\ argument\ should\ be\ a\ fixnum\ >\=0,\ not\ ~=
+
+#: hashtabl.d:1345
+!~\:\ \:REHASH-SIZE\ argument\ should\ be\ a\ float\ >\ 1,\ not\ ~=
+
+#: hashtabl.d:1390
+!~\:\ \:REHASH-THRESHOLD\ argument\ should\ be\ a\ float\ between\ 0\ and\ 1,\ not\ ~=
+
+#: hashtabl.d:1465
+!~\:\ internal\ error\ while\ building\ ~=
+
+#: hashtabl.d:1509
+!~\:\ argument\ ~\ is\ not\ a\ hash-table=
+
+#: list.d:642
+!~\:\ ~\ is\ not\ a\ nonnegative\ fixnum\ and\ therefore\ not\ a\ valid\ index=
+
+#: list.d:738
+!~\:\ ~\ is\ not\ a\ nonnegative\ integer\ and\ therefore\ not\ a\ valid\ argument=
+
+#: list.d:865
+!~\:\ ~\ is\ not\ a\ nonnegative\ fixnum\ and\ therefore\ not\ a\ valid\ list\ length=
+
+#: list.d:1174
+!~\:\ ~\ is\ not\ a\ pair=
+
+#: list.d:1921
+!~\:\ lists\ ~\ and\ ~\ are\ not\ of\ same\ length=
+
+#: list.d:2140
+!~\:\ index\ ~\ too\ large\ for\ ~=
+
+#: list.d:2202
+!~\:\ start\ index\ ~\ too\ large\ for\ ~=
+
+#: list.d:2247
+!~\:\ end\ index\ ~\ too\ large\ for\ ~=
+
+#: package.d:386
+!symbol\ ~\ cannot\ be\ deleted\ from\ symbol\ table=
+
+#: package.d:808
+!~\ inconsistent\:\ symbol\ ~\ is\ a\ shadowing\ symbol\ but\ not\ present=
+
+#: package.d:1259
+!UNEXPORT\ in\ ~\ is\ illegal=
+
+#: package.d:1278
+!UNEXPORT\ works\ only\ on\ accessible\ symbols,\ not\ on\ ~\ in\ ~=
+
+#: package.d:1924
+!The\ value\ of\ *PACKAGE*\ was\ not\ a\ package.\ Old\ value\ ~.\ New\ value\ ~.=
+
+#: package.d:1946
+!Package\ ~\ has\ been\ deleted.=
+
+#: package.d:1957
+!There\ is\ no\ package\ with\ name\ ~=
+
+#: package.d:1967
+!~\:\ argument\ should\ be\ a\ package\ or\ a\ package\ name,\ not\ ~=
+
+#: package.d:1979
+!~\:\ argument\ should\ be\ a\ string,\ not\ ~=
+
+#: package.d:2002
+!~\:\ argument\ ~\ should\ be\ a\ string\ or\ a\ symbol=
+
+#: package.d:2112
+!~\:\ there\ is\ already\ a\ package\ named\ ~=
+
+#: package.d:2248 predtype.d:1981
+!~\:\ argument\ ~\ is\ not\ a\ symbol=
+
+#: package.d:2302
+!~\:\ argument\ should\ be\ a\ symbol\ or\ a\ list\ of\ symbols,\ not\ ~=
+
+#: package.d:2537
+!Cannot\ change\ the\ case\ sensitiveness\ of\ ~.=
+
+#: record.d:35
+!~\:\ ~\ is\ not\ a\ valid\ index\ into\ ~=
+
+#: record.d:47
+!~\:\ ~\ is\ not\ a\ record=
+
+#: record.d:113
+!~\:\ length\ ~\ is\ illegal,\ should\ be\ of\ type\ (INTEGER\ (0)\ (65536))=
+
+#: record.d:151
+!~\:\ ~\ is\ not\ a\ structure\ of\ type\ ~=
+
+#: record.d:203
+!~\:\ Slot\ ~\ of\ ~\ has\ no\ value=
+
+#: record.d:313
+!~\:\ ~\ is\ not\ a\ closure=
+
+#: record.d:327
+!~\:\ This\ is\ not\ a\ compiled\ closure\:\ ~=
+
+#: record.d:401
+!~\ is\ not\ a\ valid\ code-vector\ byte=
+
+#: record.d:418
+!~\:\ invalid\ code-vector\ ~=
+
+#: record.d:428
+!~\:\ function\ ~\ is\ too\ big\:\ ~=
+
+#: record.d:459 record.d:502
+!~\:\ This\ is\ not\ a\ generic\ function\:\ ~=
+
+#: record.d:469
+!~\:\ This\ is\ not\ a\ prototype\ of\ a\ generic\ function\:\ ~=
+
+#: record.d:619
+!~\:\ ~\ is\ not\ a\ Macro=
+
+#: record.d:670 record.d:684
+!~\:\ ~\ is\ not\ a\ FunctionMacro=
+
+#: record.d:726
+!~\:\ ~\ is\ not\ a\ weak\ pointer=
+
+#: record.d:794
+!~\:\ ~\ is\ not\ a\ class=
+
+#: record.d:827
+!ALLOCATE-INSTANCE\:\ keyword\ argument\ list\ ~\ has\ an\ odd\ length=
+
+#: record.d:1035
+!~\:\ illegal\ keyword/value\ pair\ ~,\ ~\ in\ argument\ list.\nThe\ allowed\ keywords\ are\ ~=
+
+#: record.d:1071
+!SHARED-INITIALIZE\:\ keyword\ argument\ list\ ~\ has\ an\ odd\ length=
+
+#: record.d:1198
+!REINITIALIZE-INSTANCE\:\ keyword\ argument\ list\ ~\ has\ an\ odd\ length=
+
+#: record.d:1305
+!INITIALIZE-INSTANCE\:\ keyword\ argument\ list\ ~\ has\ an\ odd\ length=
+
+#: record.d:1443
+!MAKE-INSTANCE\:\ keyword\ argument\ list\ ~\ has\ an\ odd\ length=
+
+#: record.d:1509
+!~\ method\ for\ ~\ returned\ ~=
+
+#: sequence.d:219
+!There\ are\ no\ sequences\ of\ type\ ~=
+
+#: sequence.d:285
+!~\ is\ not\ a\ sequence=
+
+#: sequence.d:302
+!sequence\ type\ forces\ length\ ~,\ but\ result\ has\ length\ ~=
+
+#: sequence.d:318
+!~\:\ ~\ should\ be\ an\ integer\ >\=0,\ not\ ~=
+
+#: sequence.d:369 sequence.d:400
+!~\:\ ~\ \=\ ~\ should\ not\ be\ greater\ than\ ~\ \=\ ~=
+
+#: sequence.d:550
+!~\:\ the\ index\ should\ be\ a\ fixnum\ >\=0,\ not\ ~=
+
+#: sequence.d:567
+!~\ ~\:\ the\ index\ should\ be\ a\ fixnum\ >\=0,\ not\ ~=
+
+#: sequence.d:706
+!~\:\ ~\ is\ not\ a\ sequence=
+
+#: sequence.d:829 sequence.d:1127
+!~\:\ bad\ length\ ~=
+
+#: sequence.d:930
+!~\:\ size\ should\ be\ an\ integer\ >\=0,\ not\ ~=
+
+#: sequence.d:938
+!~\:\ \:update\ must\ not\ be\ specified\ without\ \:initial-element=
+
+#: sequence.d:1978
+!~\:\ Must\ not\ specify\ both\ arguments\ to\ \:TEST\ and\ \:TEST-NOT=
+
+#: sequence.d:2107
+!~\:\ sequence\ ~\ is\ too\ long=
+
+#: sequence.d:2569
+!too\ long\ sequence\ ~=
+
+#: charstrg.d:946 charstrg.d:1028 charstrg.d:1060 charstrg.d:1107
+!This\ is\ not\ a\ string\:\ ~=
+
+#: charstrg.d:1760
+!~\:\ the\ radix\ must\ be\ an\ integer\ between\ 2\ and\ 36,\ not\ ~=
+
+#: charstrg.d:2134
+!~\:\ the\ code\ argument\ should\ be\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2156
+!~\:\ cannot\ coerce\ ~\ to\ a\ character=
+
+#: charstrg.d:2197
+!~\:\ the\ weight\ argument\ should\ be\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2239
+!~\:\ argument\ should\ be\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2266
+!~\:\ index\ should\ be\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2271
+!~\:\ ~-index\ should\ be\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2288
+!~\:\ index\ should\ be\ NIL\ or\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2293
+!~\:\ ~-index\ should\ be\ NIL\ or\ an\ integer,\ not\ ~=
+
+#: charstrg.d:2310
+!~\:\ index\ should\ not\ be\ negative\:\ ~=
+
+#: charstrg.d:2315
+!~\:\ ~-index\ should\ not\ be\ negative\:\ ~=
+
+#: charstrg.d:2339
+!~\:\ index\ ~\ should\ not\ be\ greater\ than\ the\ length\ of\ the\ string=
+
+#: charstrg.d:2344
+!~\:\ ~-index\ ~\ should\ not\ be\ greater\ than\ the\ length\ of\ the\ string=
+
+#: charstrg.d:2368
+!~\:\ index\ ~\ should\ be\ less\ than\ the\ length\ of\ the\ string=
+
+#: charstrg.d:2373
+!~\:\ ~-index\ ~\ should\ be\ less\ than\ the\ length\ of\ the\ string=
+
+#: charstrg.d:2478
+!~\:\ argument\ should\ be\ a\ character,\ not\ ~=
+
+#: charstrg.d:2549 charstrg.d:2646 charstrg.d:3651
+!~\:\ \:start-index\ ~\ must\ not\ be\ greater\ than\ \:end-index\ ~=
+
+#: charstrg.d:2604
+!~\:\ argument\ ~\ should\ be\ a\ string,\ a\ symbol\ or\ a\ character=
+
+#: charstrg.d:2704
+!~\:\ \:start1-index\ ~\ must\ not\ be\ greater\ than\ \:end1-index\ ~=
+
+#: charstrg.d:2728
+!~\:\ \:start2-index\ ~\ must\ not\ be\ greater\ than\ \:end2-index\ ~=
+
+#: charstrg.d:3306
+!~\:\ the\ string\ length\ ~\ should\ be\ nonnegative\ fixnum=
+
+#: charstrg.d:3338
+!~\:\ \:initial-element\ ~\ should\ be\ of\ type\ character=
+
+#: debug.d:718
+!~\:\ bad\ frame\ climbing\ mode\ ~=
+
+#: debug.d:738
+!~\:\ ~\ is\ not\ a\ stack\ pointer=
+
+#: debug.d:930
+!~\:\ ~\ is\ not\ a\ pointer\ to\ an\ EVAL/APPLY\ frame=
+
+#: debug.d:1203
+!~\:\ environment\ is\ not\ an\ alist=
+
+#: debug.d:1292
+!~\:\ unknown\ frame\ type=
+
+#: error.d:49
+!Unprintable\ error\ message=
+
+#: error.d:669
+!~\:\ User\ break=
+
+#: error.d:730
+!~\:\ ~\ is\ not\ a\ list=
+
+#: error.d:746
+!~\:\ A\ true\ list\ must\ not\ end\ with\ ~=
+
+#: error.d:764
+!~\:\ ~\ is\ not\ a\ symbol=
+
+#: error.d:795
+!~\:\ ~\ is\ not\ a\ simple-vector=
+
+#: error.d:811
+!~\:\ ~\ is\ not\ a\ vector=
+
+#: error.d:827
+!~\:\ argument\ ~\ should\ be\ a\ nonnegative\ fixnum=
+
+#: error.d:843
+!~\:\ argument\ ~\ is\ not\ a\ character=
+
+#: error.d:858
+!~\:\ argument\ ~\ is\ not\ a\ string=
+
+#: error.d:873
+!~\:\ argument\ ~\ is\ not\ a\ simple\ string=
+
+#: error.d:887
+!Attempt\ to\ modify\ a\ read-only\ string\:\ ~=
+
+#: error.d:903
+!~\:\ argument\ ~\ is\ neither\ a\ string\ nor\ an\ integer=
+
+#: error.d:919
+!~\:\ argument\ ~\ should\ be\ a\ stream=
+
+#: error.d:937
+!~\:\ argument\ ~\ should\ be\ a\ stream\ of\ type\ ~=
+
+#: error.d:969
+!~\:\ argument\ ~\ is\ not\ a\ function.\nTo\ get\ a\ function\ in\ the\ current\ environment,\ write\ (FUNCTION\ ...).\nTo\ get\ a\ function\ in\ the\ global\ environment,\ write\ (COERCE\ '...\ 'FUNCTION).=
+
+#: error.d:985 error.d:1003
+!~\:\ ~\ is\ not\ an\ 8-bit\ number=
+
+#: error.d:1019 error.d:1035
+!~\:\ ~\ is\ not\ a\ 16-bit\ number=
+
+#: error.d:1051 error.d:1067
+!~\:\ ~\ is\ not\ an\ 32-bit\ number=
+
+#: error.d:1083 error.d:1099
+!~\:\ ~\ is\ not\ an\ 64-bit\ number=
+
+#: error.d:1119
+!~\:\ ~\ is\ not\ an\ `unsigned\ int'\ number=
+
+#: error.d:1139
+!~\:\ ~\ is\ not\ an\ `int'\ number=
+
+#: error.d:1159
+!~\:\ ~\ is\ not\ a\ `unsigned\ long'\ number=
+
+#: error.d:1179
+!~\:\ ~\ is\ not\ a\ `long'\ number=
+
+#: error.d:1195
+!~\:\ ~\ is\ not\ a\ single-float=
+
+#: error.d:1211
+!~\:\ ~\ is\ not\ a\ double-float=
+
+#: erramiga.d:11
+!Amiga\ OS\ error\ =
+
+#: erramiga.d:40
+!not\ enough\ memory\ available=
+
+#: erramiga.d:43
+!process\ table\ full=
+
+#: erramiga.d:53
+!bad\ template=
+
+#: erramiga.d:55
+!bad\ number=
+
+#: erramiga.d:57
+!required\ argument\ missing=
+
+#: erramiga.d:59
+!value\ after\ keyword\ missing=
+
+#: erramiga.d:61
+!wrong\ number\ of\ arguments=
+
+#: erramiga.d:63
+!unmatched\ quotes=
+
+#: erramiga.d:65
+!argument\ line\ invalid\ or\ too\ long=
+
+#: erramiga.d:67
+!file\ is\ not\ executable=
+
+#: erramiga.d:69
+!invalid\ resident\ library=
+
+#: erramiga.d:78
+!object\ is\ in\ use=
+
+#: erramiga.d:80
+!object\ already\ exists=
+
+#: erramiga.d:82
+!directory\ not\ found=
+
+#: erramiga.d:84
+!object\ not\ found=
+
+#: erramiga.d:86
+!invalid\ window\ description=
+
+#: erramiga.d:88
+!object\ too\ large=
+
+#: erramiga.d:91
+!packet\ request\ type\ unknown=
+
+#: erramiga.d:93
+!object\ name\ invalid=
+
+#: erramiga.d:95
+!invalid\ object\ lock=
+
+#: erramiga.d:97
+!object\ is\ not\ of\ required\ type=
+
+#: erramiga.d:99
+!disk\ not\ validated=
+
+#: erramiga.d:101
+!disk\ is\ write-protected=
+
+#: erramiga.d:103
+!rename\ across\ devices\ attempted=
+
+#: erramiga.d:105
+!directory\ not\ empty=
+
+#: erramiga.d:107
+!too\ many\ levels=
+
+#: erramiga.d:109
+!device\ (or\ volume)\ is\ not\ mounted=
+
+#: erramiga.d:111
+!seek\ failure=
+
+#: erramiga.d:113
+!comment\ is\ too\ long=
+
+#: erramiga.d:115
+!disk\ is\ full=
+
+#: erramiga.d:117
+!object\ is\ protected\ from\ deletion=
+
+#: erramiga.d:119
+!file\ is\ write\ protected=
+
+#: erramiga.d:121
+!file\ is\ read\ protected=
+
+#: erramiga.d:123
+!not\ a\ valid\ DOS\ disk=
+
+#: erramiga.d:125
+!no\ disk\ in\ drive=
+
+#: erramiga.d:132
+!no\ more\ entries\ in\ directory=
+
+#: erramiga.d:134
+!object\ is\ soft\ link=
+
+#: erramiga.d:136
+!object\ is\ linked=
+
+#: erramiga.d:138
+!bad\ loadfile\ hunk=
+
+#: erramiga.d:140
+!function\ not\ implemented=
+
+#: erramiga.d:145
+!record\ not\ locked=
+
+#: erramiga.d:147
+!record\ lock\ collision=
+
+#: erramiga.d:149
+!record\ lock\ timeout=
+
+#: erramiga.d:151
+!record\ unlock\ error=
+
+#: erramiga.d:158
+!buffer\ overflow=
+
+#: erramiga.d:160
+!break=
+
+#: erramiga.d:162
+!file\ not\ executable=
+
+#: erramiga.d:170
+!Ok,\ No\ error=
+
+#: errunix.d:57
+!Operation\ not\ permitted=
+
+#: errunix.d:63
+!No\ such\ file\ or\ directory=
+
+#: errunix.d:69
+!No\ such\ process=
+
+#: errunix.d:75
+!Interrupted\ system\ call=
+
+#: errunix.d:81
+!I/O\ error=
+
+#: errunix.d:87
+!No\ such\ device\ or\ address=
+
+#: errunix.d:93
+!Arg\ list\ too\ long=
+
+#: errunix.d:99
+!Exec\ format\ error=
+
+#: errunix.d:105
+!Bad\ file\ number=
+
+#: errunix.d:111
+!No\ child\ processes=
+
+#: errunix.d:117
+!No\ more\ processes=
+
+#: errunix.d:123
+!Not\ enough\ memory=
+
+#: errunix.d:129
+!Permission\ denied=
+
+#: errunix.d:135
+!Bad\ address=
+
+#: errunix.d:141
+!Block\ device\ required=
+
+#: errunix.d:147
+!Device\ busy=
+
+#: errunix.d:153
+!File\ exists=
+
+#: errunix.d:159
+!Cross-device\ link=
+
+#: errunix.d:165
+!No\ such\ device=
+
+#: errunix.d:171
+!Not\ a\ directory=
+
+#: errunix.d:177
+!Is\ a\ directory=
+
+#: errunix.d:183
+!Invalid\ argument=
+
+#: errunix.d:189
+!File\ table\ overflow=
+
+#: errunix.d:195
+!Too\ many\ open\ files=
+
+#: errunix.d:201
+!Inappropriate\ ioctl\ for\ device=
+
+#: errunix.d:207
+!Text\ file\ busy=
+
+#: errunix.d:213
+!File\ too\ large=
+
+#: errunix.d:219
+!No\ space\ left\ on\ device=
+
+#: errunix.d:225
+!Illegal\ seek=
+
+#: errunix.d:231
+!Read-only\ file\ system=
+
+#: errunix.d:237
+!Too\ many\ links=
+
+#: errunix.d:243
+!Broken\ pipe,\ child\ process\ terminated\ or\ socket\ closed=
+
+#: errunix.d:253
+!Argument\ out\ of\ domain=
+
+#: errunix.d:259
+!Result\ too\ large=
+
+#: errunix.d:266
+!Invalid\ multibyte\ or\ wide\ character=
+
+#: errunix.d:273
+!Operation\ would\ block=
+
+#: errunix.d:279
+!Operation\ now\ in\ progress=
+
+#: errunix.d:285
+!Operation\ already\ in\ progress=
+
+#: errunix.d:292
+!Too\ many\ levels\ of\ symbolic\ links=
+
+#: errunix.d:298
+!File\ name\ too\ long=
+
+#: errunix.d:304
+!Directory\ not\ empty=
+
+#: errunix.d:311
+!Stale\ NFS\ file\ handle=
+
+#: errunix.d:317
+!Too\ many\ levels\ of\ remote\ in\ path=
+
+#: errunix.d:324
+!Socket\ operation\ on\ non-socket=
+
+#: errunix.d:330
+!Destination\ address\ required=
+
+#: errunix.d:336
+!Message\ too\ long=
+
+#: errunix.d:342
+!Protocol\ wrong\ type\ for\ socket=
+
+#: errunix.d:348
+!Option\ not\ supported\ by\ protocol=
+
+#: errunix.d:354
+!Protocol\ not\ supported=
+
+#: errunix.d:360
+!Socket\ type\ not\ supported=
+
+#: errunix.d:366
+!Operation\ not\ supported\ on\ socket=
+
+#: errunix.d:372
+!Protocol\ family\ not\ supported=
+
+#: errunix.d:378
+!Address\ family\ not\ supported\ by\ protocol\ family=
+
+#: errunix.d:384
+!Address\ already\ in\ use=
+
+#: errunix.d:390
+!Can't\ assign\ requested\ address=
+
+#: errunix.d:396
+!Network\ is\ down=
+
+#: errunix.d:402
+!Network\ is\ unreachable=
+
+#: errunix.d:408
+!Network\ dropped\ connection\ on\ reset=
+
+#: errunix.d:414
+!Software\ caused\ connection\ abort=
+
+#: errunix.d:420
+!Connection\ reset\ by\ peer=
+
+#: errunix.d:426
+!No\ buffer\ space\ available=
+
+#: errunix.d:432
+!Socket\ is\ already\ connected=
+
+#: errunix.d:438
+!Socket\ is\ not\ connected=
+
+#: errunix.d:444
+!Can't\ send\ after\ socket\ shutdown=
+
+#: errunix.d:450
+!Too\ many\ references\:\ can't\ splice=
+
+#: errunix.d:456
+!Connection\ timed\ out=
+
+#: errunix.d:462
+!Connection\ refused=
+
+#: errunix.d:467
+!Remote\ peer\ released\ connection=
+
+#: errunix.d:472
+!Host\ is\ down=
+
+#: errunix.d:478
+!Host\ is\ unreachable=
+
+#: errunix.d:483
+!Networking\ error=
+
+#: errunix.d:489
+!Too\ many\ processes=
+
+#: errunix.d:495
+!Too\ many\ users=
+
+#: errunix.d:501
+!Disk\ quota\ exceeded=
+
+#: errunix.d:508
+!Not\ a\ stream\ device=
+
+#: errunix.d:514
+!Timer\ expired=
+
+#: errunix.d:520
+!Out\ of\ stream\ resources=
+
+#: errunix.d:526
+!No\ message\ of\ desired\ type=
+
+#: errunix.d:532
+!Not\ a\ data\ message=
+
+#: errunix.d:539
+!Identifier\ removed=
+
+#: errunix.d:546
+!Resource\ deadlock\ would\ occur=
+
+#: errunix.d:552
+!No\ record\ locks\ available=
+
+#: errunix.d:559
+!Machine\ is\ not\ on\ the\ network=
+
+#: errunix.d:565 errunix.d:571
+!Object\ is\ remote=
+
+#: errunix.d:577
+!Link\ has\ been\ severed=
+
+#: errunix.d:583
+!Advertise\ error=
+
+#: errunix.d:589
+!Srmount\ error=
+
+#: errunix.d:595
+!Communication\ error\ on\ send=
+
+#: errunix.d:601
+!Protocol\ error=
+
+#: errunix.d:607
+!Multihop\ attempted=
+
+#: errunix.d:619
+!Remote\ address\ changed=
+
+#: errunix.d:626
+!Function\ not\ implemented=
+
+#: errunix.d:633
+!Not\ supported\ under\ MS-DOS=
+
+#: errunix.d:664
+!UNIX\ error\ =
+
+#: errunix.d:666
+!UNIX\ library\ error\ =
+
+#: errwin32.d:3880
+!Win32\ error\ =
+
+#: errwin32.d:3929
+!Winsock\ error\ =
+
+#: misc.d:108
+!This\ file\ was\ produced\ by\ another\ lisp\ version,\ must\ be\ recompiled.=
+
+#: misc.d:325
+!~\:\ type\ of\ attribute\ ~\ is\ unsupported=
+
+#: predtype.d:1736 predtype.d:1940
+!~\:\ unidentifiable\ type\!\!\!=
+
+#: predtype.d:1947
+!~\:\ type\ ~\ does\ not\ correspond\ to\ a\ class=
+
+#: predtype.d:1990
+!~\:\ ~\ does\ not\ name\ a\ class=
+
+#: predtype.d:2301
+!~\:\ bad\ type\ specification\ ~=
+
+#: predtype.d:2309
+!~\:\ ~\ cannot\ be\ coerced\ to\ type\ ~=
+
+#: symbol.d:48
+!~\:\ the\ property\ list\ of\ ~\ has\ an\ odd\ length=
+
+#: symbol.d:104
+!SETF\ SYMBOL-FUNCTION\:\ ~\ is\ not\ a\ function=
+
+#: symbol.d:129
+!~\:\ ~\ is\ not\ a\ system\ function=
+
+#: symbol.d:188 symbol.d:229
+!~\:\ the\ property\ list\ ~\ has\ an\ odd\ length=
+
+#: symbol.d:419 intlog.d:592
+!~\:\ index\ ~\ is\ negative=
+
+#: symbol.d:430
+!~\:\ invalid\ argument\ ~=
+
+#: symbol.d:444
+!The\ value\ of\ *GENSYM-COUNTER*\ was\ not\ a\ nonnegative\ integer.\ Old\ value\ ~.\ New\ value\ ~.=
+
+#: lisparit.d:359
+!argument\ to\ ~\ should\ be\ a\ number\:\ ~=
+
+#: lisparit.d:375
+!argument\ to\ ~\ should\ be\ a\ real\ number\:\ ~=
+
+#: lisparit.d:391
+!argument\ to\ ~\ should\ be\ a\ floating\ point\ number\:\ ~=
+
+#: lisparit.d:407
+!argument\ to\ ~\ should\ be\ a\ rational\ number\:\ ~=
+
+#: lisparit.d:423
+!argument\ to\ ~\ should\ be\ an\ integer\:\ ~=
+
+#: lisparit.d:439
+!~\:\ argument\ should\ be\ a\ positive\ fixnum,\ not\ ~=
+
+#: lisparit.d:1846
+!~\:\ argument\ should\ be\ a\ random-state,\ not\ ~=
+
+#: lisparit.d:1861
+!~\:\ the\ value\ of\ ~\ should\ be\ a\ random-state,\ not\ ~=
+
+#: lisparit.d:1885
+!~\:\ argument\ should\ be\ positive\ and\ an\ integer\ or\ float,\ not\ ~=
+
+#: lisparit.d:1970
+!~\ \:\ argument\ should\ be\ a\ fixnum\ >\=0,\ not\ ~=
+
+#: aridecl.d:338
+!division\ by\ zero=
+
+#: aridecl.d:348
+!floating\ point\ overflow=
+
+#: aridecl.d:358
+!floating\ point\ underflow=
+
+#: intelem.d:211 intelem.d:309
+!not\ a\ 32-bit\ integer\:\ ~=
+
+#: intelem.d:399 intelem.d:545
+!not\ a\ 64-bit\ integer\:\ ~=
+
+#: intelem.d:1443
+!bignum\ overflow=
+
+#: intlog.d:469
+!~\:\ ~\ is\ not\ a\ valid\ boolean\ operation=
+
+#: intlog.d:725
+!~\:\ too\ large\ shift\ amount\ ~=
+
+#: intbyte.d:16
+!The\ arguments\ to\ BYTE\ must\ be\ fixnums\ >\=0\:\ ~,\ ~=
+
+#: intbyte.d:40
+!~\ is\ not\ a\ BYTE\ specifier=
+
+#: intmal.d:8
+!overflow\ during\ multiplication\ of\ large\ numbers=
+
+#: intdiv.d:373
+!quotient\ ~\ /\ ~\ is\ not\ an\ integer=
+
+#: intsqrt.d:426
+!~\ applied\ to\ negative\ number\ ~=
+
+#: lfloat.d:8
+!long\ float\ too\ long=
+
+#: flo_konv.d:465
+!floating\ point\ NaN\ occurred=
+
+#: rexx.d:34
+!Communication\ with\ ARexx\ isn't\ possible.=
+
+#: rexx.d:116
+!~\ must\ be\ a\ string\ for\ commands\ or\ a\ vector\ of\ strings\ for\ a\ function=
+
+#: rexx.d:125
+!~\:\ an\ ARexx\ function\ must\ have\ 0\ to\ ~\ arguments\:\ ~=
+
+#: rexx.d:139
+!~\:\ must\ be\ a\ string\ for\ ARexx\:\ ~=
+
+#: rexx.d:161
+!Only\ NIL,\ T\ and\ strings\ are\ accepted\ for\ ~\ \:\ ~=
+
+#: rexx.d:474
+!~\:\ Not\ a\ Fixnum\:\ ~=
+
+#: rexx.d:484
+!~\:\ Not\ an\ incoming\ Rexx\ message\:\ ~=
+
+#: affi.d:85
+!~\:\ Unsupported\ call\ mechanism\:\ ~=
+
+#: affi.d:96
+!~\:\ Bad\ function\ prototype\:\ ~=
+
+#: affi.d:107
+!~\:\ Wrong\ number\ of\ arguments\ for\ prototype\ ~=
+
+#: affi.d:121
+!~\:\ Bad\ argument\ for\ prototype\ ~\:\ ~=
+
+#: affi.d:132
+!~\:\ Bad\ argument\:\ ~=
+
+#: affi.d:153
+!~\:\ ~\ is\ not\ a\ valid\ address=
+
+#: foreign.d:27
+!~\ comes\ from\ a\ previous\ Lisp\ session\ and\ is\ invalid=
+
+#: foreign.d:100
+!A\ foreign\ variable\ ~\ already\ exists=
+
+#: foreign.d:140
+!A\ foreign\ function\ ~\ already\ exists=
+
+#: foreign.d:182
+!illegal\ foreign\ data\ type\ ~=
+
+#: foreign.d:196
+!~\ cannot\ be\ converted\ to\ the\ foreign\ type\ ~=
+
+#: foreign.d:209
+!64\ bit\ integers\ are\ not\ supported\ on\ this\ platform\ and\ with\ this\ C\ compiler\:\ ~=
+
+#: foreign.d:353 foreign.d:519
+!~\ cannot\ be\ converted\ to\ a\ foreign\ function\ with\ another\ calling\ convention.=
+
+#: foreign.d:564
+!No\ more\ room\ for\ foreign\ language\ interface=
+
+#: foreign.d:573
+!\:MALLOC-FREE\ is\ not\ available\ under\ AMIGAOS.=
+
+#: foreign.d:1101 foreign.d:1162 foreign.d:1317 foreign.d:1363
+!element\ type\ has\ size\ 0\:\ ~=
+
+#: foreign.d:2113
+!~\:\ argument\ is\ not\ a\ foreign\ variable\:\ ~=
+
+#: foreign.d:2123
+!~\:\ foreign\ variable\ with\ unknown\ type,\ missing\ DEF-C-VAR\:\ ~=
+
+#: foreign.d:2137
+!A\ foreign\ variable\ ~\ does\ not\ exist=
+
+#: foreign.d:2149
+!~\:\ foreign\ variable\ ~\ does\ not\ have\ the\ required\ size\ or\ alignment=
+
+#: foreign.d:2163
+!~\:\ type\ specifications\ for\ foreign\ variable\ ~\ conflict\:\ ~\ and\ ~=
+
+#: foreign.d:2212
+!~\:\ foreign\ variable\ ~\ may\ not\ be\ modified=
+
+#: foreign.d:2272
+!~\:\ foreign\ variable\ ~\ of\ type\ ~\ is\ not\ an\ array=
+
+#: foreign.d:2358
+!~\:\ foreign\ variable\ ~\ of\ type\ ~\ is\ not\ a\ pointer=
+
+#: foreign.d:2462
+!~\:\ foreign\ variable\ ~\ of\ type\ ~\ is\ not\ a\ struct\ or\ union=
+
+#: foreign.d:2471
+!~\:\ foreign\ variable\ ~\ of\ type\ ~\ has\ no\ component\ with\ name\ ~=
+
+#: foreign.d:2541 foreign.d:3634
+!~\:\ foreign\ variable\ ~\ does\ not\ have\ the\ required\ alignment=
+
+#: foreign.d:2557
+!~\:\ argument\ is\ not\ a\ foreign\ function\:\ ~=
+
+#: foreign.d:2568
+!~\:\ foreign\ function\ with\ unknown\ calling\ convention,\ missing\ DEF-CALL-OUT\:\ ~=
+
+#: foreign.d:2586 foreign.d:3660
+!~\:\ illegal\ foreign\ function\ type\ ~=
+
+#: foreign.d:2594
+!~\:\ A\ foreign\ function\ ~\ does\ not\ exist=
+
+#: foreign.d:2601
+!~\:\ calling\ conventions\ for\ foreign\ function\ ~\ conflict=
+
+#: foreign.d:2884
+!~\:\ Too\ few\ arguments\ (~\ instead\ of\ at\ least\ ~)\ to\ ~=
+
+#: foreign.d:2896
+!~\:\ \:OUT\ argument\ is\ not\ a\ pointer\:\ ~=
+
+#: foreign.d:2941
+!~\:\ Too\ many\ arguments\ (~\ instead\ of\ ~)\ to\ ~=
+
+#: foreign.d:3510
+!~\:\ Cannot\ open\ library\ ~=
+
+#: foreign.d:3608
+!~\:\ ~\ is\ not\ a\ library=
+
+#: amigaaux.d:212
+!This\ version\ of\ CLISP\ runs\ only\ in\ low\ address\ memory.\n=
+
+#: init.lisp:347
+!~S\ is\ a\ special\ form\ and\ may\ not\ be\ redefined.=
+
+#: init.lisp:353 clos.lisp:205
+!The\ old\ definition\ will\ be\ lost=
+
+#: init.lisp:354
+!Redefining\ the\ COMMON\ LISP\ ~A\ ~S=
+
+#: init.lisp:371
+!DEFUN/DEFMACRO\:\ redefining\ ~S;\ it\ was\ traced\!=
+
+#: init.lisp:391
+!~S\ is\ impossible\ in\ compiled\ code=
+
+#: init.lisp:478
+!~S\ is\ an\ invalid\ function\ environment=
+
+#: init.lisp:525
+!~S\ is\ an\ invalid\ variable\ environment=
+
+#: init.lisp:592
+!~S\:\ ~S\ is\ illegal\ since\ ~S\ is\ a\ local\ macro=
+
+#: init.lisp:596
+!~S\:\ invalid\ function\ environment\ ~S=
+
+#: init.lisp:602
+!~S\:\ ~S\ is\ invalid\ since\ ~S\ is\ not\ a\ symbol=
+
+#: init.lisp:776
+!code\ after\ MACROLET\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: init.lisp:792
+!illegal\ syntax\ in\ MACROLET\:\ ~S=
+
+#: init.lisp:813
+!code\ after\ SYMBOL-MACROLET\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: init.lisp:822 compiler.lisp:7388
+!~S\:\ symbol\ ~S\ must\ not\ be\ declared\ SPECIAL\ and\ a\ macro\ at\ the\ same\ time=
+
+#: init.lisp:837 compiler.lisp:7383
+!~S\:\ symbol\ ~S\ is\ declared\ special\ and\ must\ not\ be\ declared\ a\ macro=
+
+#: init.lisp:844
+!illegal\ syntax\ in\ SYMBOL-MACROLET\:\ ~S=
+
+#: init.lisp:883
+!bad\ function\ environment\ occurred\ in\ ~S\:\ ~S=
+
+#: init.lisp:892
+!~S\:\ invalid\ form\ ~S=
+
+#: init.lisp:903
+!code\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: init.lisp:946
+!~S\:\ ~S\ should\ be\ a\ lambda\ expression=
+
+#: init.lisp:987
+!lambda\ list\ must\ not\ end\ with\ the\ atom\ ~S=
+
+#: init.lisp:1019 init.lisp:1036
+!~S\:\ variable\ list\ ends\ with\ the\ atom\ ~S=
+
+#: init.lisp:1149
+!FLET/LABELS\:\ code\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: init.lisp:1158
+!illegal\ syntax\ in\ FLET/LABELS\:\ ~S=
+
+#: init.lisp:1179
+!FUNCTION-MACRO-LET\:\ code\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: init.lisp:1193
+!illegal\ syntax\ in\ FUNCTION-MACRO-LET\:\ ~S=
+
+#: init.lisp:1350
+!Loading\ file\ =
+
+#: init.lisp:1352
+!\ ...=
+
+#: init.lisp:1378
+!Loading\ of\ file\ =
+
+#: init.lisp:1380
+!\ is\ finished.=
+
+#: init.lisp:1387
+!A\ file\ with\ name\ ~A\ does\ not\ exist=
+
+#: init.lisp:1401
+!~S\:\ missing\ function\ name\ and/or\ parameter\ list=
+
+#: init.lisp:1409
+!~S\:\ ~S\ is\ not\ a\ symbol.=
+
+#: init.lisp:1414
+!~S\:\ special\ operator\ ~S\ cannot\ be\ redefined.=
+
+#: init.lisp:1459 macros1.lisp:145
+!exit\ clause\ in\ ~S\ must\ be\ a\ list=
+
+#: init.lisp:1610
+!~S\:\ cannot\ define\ a\ function\ from\ that\:\ ~S=
+
+#: init.lisp:1615 clos.lisp:2996 clos.lisp:3053
+!~S\:\ the\ name\ of\ a\ function\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: init.lisp:1620
+!~S\:\ function\ ~S\ is\ missing\ a\ lambda\ list=
+
+#: init.lisp:1843 condition.lisp:1475 reploop.lisp:414
+!If\ you\ continue\ (by\ typing\ 'continue')\:\ =
+
+#: backquote.lisp:39
+!~S\:\ comma\ is\ illegal\ outside\ of\ backquote=
+
+#: backquote.lisp:44
+!~S\:\ more\ commas\ out\ than\ backquotes\ in,\ is\ illegal=
+
+#: backquote.lisp:205
+!The\ syntax\ ,@form\ is\ valid\ only\ in\ lists=
+
+#: backquote.lisp:210
+!The\ syntax\ ,.form\ is\ valid\ only\ in\ lists=
+
+#: defmacro.lisp:44
+!Both\ will\ be\ ignored.=
+
+#: defmacro.lisp:45
+!Invalid\ keyword-value-pair\:\ ~S\ ~S=
+
+#: defmacro.lisp:54
+!The\ macro\ ~S\ may\ not\ be\ called\ with\ ~S\ arguments\:\ ~S=
+
+#: defmacro.lisp:125 defmacro.lisp:150 defmacro.lisp:301
+!The\ rest\ of\ the\ lambda\ list\ will\ be\ ignored.=
+
+#: defmacro.lisp:126
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ a\ dot\ after\ &AUX.=
+
+#: defmacro.lisp:132
+!in\ macro\ ~S\:\ ~S\ may\ not\ be\ used\ as\ &AUX\ variable.=
+
+#: defmacro.lisp:151
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ a\ dot\ after\ &KEY.=
+
+#: defmacro.lisp:160 defmacro.lisp:178 defmacro.lisp:380 defmacro.lisp:396
+#: defmacro.lisp:401
+!It\ will\ be\ ignored.=
+
+#: defmacro.lisp:161
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ a\ badly\ placed\ ~S.=
+
+#: defmacro.lisp:179
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ the\ invalid\ element\ ~S=
+
+#: defmacro.lisp:209
+!~0*It\ will\ be\ ignored.=
+
+#: defmacro.lisp:210
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ an\ invalid\ keyword\ specification\ ~S=
+
+#: defmacro.lisp:281
+!The\ lambda\ list\ of\ macro\ ~S\ is\ missing\ a\ variable\ after\ &REST/&BODY.=
+
+#: defmacro.lisp:292
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ an\ illegal\ variable\ after\ &REST/&BODY\:\ ~S=
+
+#: defmacro.lisp:302
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ a\ misplaced\ dot.=
+
+#: defmacro.lisp:307
+!They\ will\ be\ ignored.=
+
+#: defmacro.lisp:308
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ superfluous\ elements\:\ ~S=
+
+#: defmacro.lisp:361
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ an\ illegal\ &REST\ variable\:\ ~S=
+
+#: defmacro.lisp:375
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ an\ invalid\ &WHOLE\:\ ~S=
+
+#: defmacro.lisp:381
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ a\ superfluous\ ~S.=
+
+#: defmacro.lisp:397
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ ~S\ before\ &KEY.=
+
+#: defmacro.lisp:402
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ ~S\ which\ is\ illegal\ here.=
+
+#: defmacro.lisp:421
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ an\ invalid\ element\ ~S=
+
+#: defmacro.lisp:435
+!The\ lambda\ list\ of\ macro\ ~S\ contains\ an\ invalid\ supplied-variable\ ~S=
+
+#: defmacro.lisp:497
+!In\ the\ lambda\ list\ of\ macro\ ~S,\ &ENVIRONMENT\ must\ be\ followed\ by\ a\ non-NIL\ symbol\:\ ~S=
+
+#: defmacro.lisp:519
+!Cannot\ define\ a\ macro\ from\ that\:\ ~S=
+
+#: defmacro.lisp:524
+!The\ name\ of\ a\ macro\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: defmacro.lisp:529
+!Macro\ ~S\ is\ missing\ a\ lambda\ list.=
+
+#: macros1.lisp:20 macros1.lisp:43
+!~S\:\ non-symbol\ ~S\ can't\ be\ a\ variable=
+
+#: macros1.lisp:25 macros1.lisp:48
+!~S\:\ the\ constant\ ~S\ must\ not\ be\ redefined\ to\ be\ a\ variable=
+
+#: macros1.lisp:62
+!~S\:\ non-symbol\ ~S\ can't\ be\ a\ defined\ constant=
+
+#: macros1.lisp:95
+!~S\ redefines\ the\ constant\ ~S.\ Its\ old\ value\ was\ ~S.=
+
+#: macros1.lisp:150
+!Invalid\ syntax\ in\ ~S\ form\:\ ~S.=
+
+#: macros1.lisp:265 places.lisp:697
+!~S\ called\ with\ an\ odd\ number\ of\ arguments\:\ ~S=
+
+#: macros1.lisp:307
+!~S\:\ missing\ key\ list=
+
+#: macros1.lisp:314
+!~S\:\ the\ ~S\ clause\ must\ be\ the\ last\ one=
+
+#: macros1.lisp:365 macros1.lisp:435
+!Not\ a\ list\ of\ COND\ clauses\:\ ~S=
+
+#: macros1.lisp:370 macros1.lisp:440
+!The\ atom\ ~S\ must\ not\ be\ used\ as\ a\ COND\ clause.=
+
+#: macros1.lisp:405
+!COND\ code\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: macros1.lisp:411 compiler.lisp:7439
+!COND\ clause\ without\ test\:\ ~S=
+
+#: macros2.lisp:40
+!Language\ ~S\ is\ not\ defined=
+
+#: macros2.lisp:50
+!Language\ ~S\ inherits\ from\ ~S=
+
+#: macros2.lisp:100
+!~S\:\ Language\ ~S\ is\ not\ defined=
+
+#: macros2.lisp:123
+!~S\ ~S\:\ no\ value\ for\ default\ language\ ~S=
+
+#: macros2.lisp:138
+!Invalid\ clause\ in\ ~S\:\ ~S=
+
+#: macros2.lisp:157
+!~A~%The\ value\ is\:\ ~S=
+
+#: macros2.lisp:161
+!The\ value\ of\ ~S\ should\ be\ ~\:[of\ type\ ~S~;~\:*~A~].=
+
+#: macros2.lisp:165
+!You\ may\ input\ a\ new\ value.=
+
+#: macros2.lisp:168
+!~%New\ ~S\:\ =
+
+#: macros2.lisp:189
+!Retry=
+
+#: macros2.lisp:192
+!You\ may\ input\ new\ values.=
+
+#: macros2.lisp:196
+!~S\ must\ evaluate\ to\ a\ non-NIL\ value.=
+
+#: macros2.lisp:232
+!The\ value\ of\ ~S\ must\ be\ of\ one\ of\ the\ types\ ~{~S~^,\ ~}=
+
+#: macros2.lisp:237
+!The\ value\ of\ ~S\ must\ be\ one\ of\ ~{~S~^,\ ~}=
+
+#: macros2.lisp:253 condition.lisp:1303
+!~S\ used\ as\ a\ key\ in\ ~S,\ it\ would\ be\ better\ to\ use\ parentheses.=
+
+#: macros2.lisp:338
+!type\ name\ should\ be\ a\ symbol,\ not\ ~S=
+
+#: macros2.lisp:343
+!~S\ is\ a\ built-in\ type\ and\ may\ not\ be\ redefined.=
+
+#: macros2.lisp:376
+!The\ deftype\ expander\ for\ ~S\ may\ not\ be\ called\ with\ ~S\ arguments.=
+
+#: macros2.lisp:384
+!~S\:\ the\ name\ of\ a\ symbol\ macro\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: macros2.lisp:399
+!~S\:\ the\ symbol\ ~S\ names\ a\ global\ variable=
+
+#: defs1.lisp:98
+!missing\ symbol\ types\ (~S/~S/~S)\ in\ ~S=
+
+#: defs1.lisp:105
+!~S\:\ flag\ must\ be\ one\ of\ the\ symbols\ ~S,\ ~S,\ ~S,\ not\ ~S=
+
+#: defs1.lisp:418
+!~S\:\ ~S\ does\ not\ name\ a\ logical\ host=
+
+#: defs1.lisp:456
+!No\ translations\ for\ logical\ host\ ~S\ found=
+
+#: defs1.lisp:542
+!~S\:\ argument\ ~S\ should\ be\ a\ nonnegative\ number=
+
+#: defs1.lisp:704
+!incorrect\ date\:\ ~S.~S.~S,\ ~Sh~Sm~Ss,\ time\ zone\ ~S=
+
+#: defs1.lisp:773
+!special\ operator=
+
+#: defs1.lisp:776
+!function=
+
+#: defs1.lisp:778
+!macro=
+
+#: places.lisp:24
+!The\ function\ (~S\ ~S)\ is\ hidden\ by\ a\ SETF\ expander.=
+
+#: places.lisp:85
+!The\ argument\ ~S\ to\ ~S\ should\ be\ a\ keyword.=
+
+#: places.lisp:140
+!Argument\ ~S\ is\ not\ a\ SETF\ place.=
+
+#: places.lisp:153
+!SETF\ place\ ~S\ produces\ more\ than\ one\ store\ variable.=
+
+#: places.lisp:177 places.lisp:185
+!~S\:\ first\ argument\ ~S\ is\ illegal,\ not\ a\ symbol=
+
+#: places.lisp:221
+!The\ name\ of\ the\ access\ function\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: places.lisp:254
+!The\ SETF\ expander\ for\ ~S\ may\ not\ be\ called\ with\ ~S\ arguments.=
+
+#: places.lisp:291
+!Too\ many\ arguments\ to\ DEFSETF\:\ ~S=
+
+#: places.lisp:295
+!The\ doc\ string\ to\ DEFSETF\ must\ be\ a\ string\:\ ~S=
+
+#: places.lisp:305
+!Missing\ store\ variable\ in\ DEFSETF.=
+
+#: places.lisp:346
+!Illegal\ syntax\ in\ DEFSETF\ for\ ~S=
+
+#: places.lisp:359
+!(SETF\ (NTH\ ...)\ ...)\ \:\ index\ ~S\ is\ too\ large\ for\ ~S=
+
+#: places.lisp:459
+!PSETF\ called\ with\ an\ odd\ number\ of\ arguments\:\ ~S=
+
+#: places.lisp:505
+!REMF\:\ property\ list\ with\ an\ odd\ length=
+
+#: places.lisp:555
+!In\ the\ definition\ of\ ~S\:\ &REST\ variable\ ~S\ should\ be\ a\ symbol.=
+
+#: places.lisp:561
+!Only\ one\ variable\ is\ allowed\ after\ &REST,\ not\ ~S=
+
+#: places.lisp:566
+!Illegal\ in\ a\ DEFINE-MODIFY-MACRO\ lambda\ list\:\ ~S=
+
+#: places.lisp:574
+!lambda\ list\ may\ only\ contain\ symbols\ and\ lists,\ not\ ~S=
+
+#: places.lisp:691
+!Illegal\ SETF\ place\:\ ~S=
+
+#: places.lisp:710
+!SHIFTF\ called\ with\ too\ few\ arguments\:\ ~S=
+
+#: places.lisp:750
+!(SETF\ (GETF\ ...)\ ...)\ \:\ property\ list\ with\ an\ odd\ length=
+
+#: places.lisp:785
+!first\ argument\ ~S\ is\ illegal,\ not\ a\ symbol=
+
+#: places.lisp:896
+!SETF\ APPLY\ is\ only\ defined\ for\ functions\ of\ the\ form\ \#'symbol.=
+
+#: places.lisp:902
+!APPLY\ on\ ~S\ is\ not\ a\ SETF\ place.=
+
+#: places.lisp:957
+!SETF\ FUNCALL\ is\ only\ defined\ for\ functions\ of\ the\ form\ \#'symbol.=
+
+#: places.lisp:1004
+!SETF\ place\ ~S\ expects\ different\ numbers\ of\ values\ in\ the\ true\ and\ branches\ (~D\ vs.\ ~D\ values).=
+
+#: floatprint.lisp:341
+!argument\ is\ not\ a\ float\:\ ~S=
+
+#: type.lisp:30
+!~S\:\ invalid\ type\ specification\ ~S=
+
+#: type.lisp:61 compiler.lisp:8580
+!~S\:\ argument\ to\ SATISFIES\ must\ be\ a\ symbol\:\ ~S=
+
+#: type.lisp:331 type.lisp:340 type.lisp:350 type.lisp:360
+!~S\:\ argument\ to\ ~S\ must\ be\ *,\ ~S\ or\ a\ list\ of\ ~S\:\ ~S=
+
+#: type.lisp:447
+!~S\:\ argument\ to\ MOD\ must\ be\ an\ integer\:\ ~S=
+
+#: type.lisp:455
+!~S\:\ argument\ to\ SIGNED-BYTE\ must\ be\ an\ integer\ or\ *\ \:\ ~S=
+
+#: type.lisp:465
+!~S\:\ argument\ to\ UNSIGNED-BYTE\ must\ be\ an\ integer\ or\ *\ \:\ ~S=
+
+#: type.lisp:639
+!Invalid\ type\ specifier\ ~S=
+
+#: defstruct.lisp:63 foreign1.lisp:423
+!~S\:\ this\ is\ not\ a\ symbol\:\ ~S=
+
+#: defstruct.lisp:425
+!~S\:\ invalid\ syntax\ for\ name\ and\ options\:\ ~S=
+
+#: defstruct.lisp:449
+!~S\ ~S\:\ argument\ list\ should\ be\ a\ list\:\ ~S=
+
+#: defstruct.lisp:472
+!~S\ ~S\:\ At\ most\ one\ \:INCLUDE\ argument\ may\ be\ specified\:\ ~S=
+
+#: defstruct.lisp:480
+!~S\:\ Use\ of\ ~S\ implicitly\ applies\ FUNCTION.~@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Therefore\ using\ ~S\ instead\ of\ ~S.=
+
+#: defstruct.lisp:493 condition.lisp:106
+!~S\ ~S\:\ unknown\ option\ ~S=
+
+#: defstruct.lisp:497 clos.lisp:3131 condition.lisp:112
+!~S\ ~S\:\ invalid\ syntax\ in\ ~S\ option\:\ ~S=
+
+#: defstruct.lisp:501 clos.lisp:3066 condition.lisp:116
+!~S\ ~S\:\ not\ a\ ~S\ option\:\ ~S=
+
+#: defstruct.lisp:525
+!~S\ ~S\:\ There\ is\ no\ \:PREDICATE\ on\ unnamed\ structures.=
+
+#: defstruct.lisp:551
+!~S\ ~S\:\ invalid\ \:TYPE\ option\ ~S=
+
+#: defstruct.lisp:557
+!~S\ ~S\:\ The\ \:INITIAL-OFFSET\ must\ be\ a\ nonnegative\ integer,\ not\ ~S=
+
+#: defstruct.lisp:563
+!~S\ ~S\:\ \:INITIAL-OFFSET\ must\ not\ be\ specified\ without\ \:TYPE\ \:\ ~S=
+
+#: defstruct.lisp:581
+!~S\ ~S\:\ included\ structure\ ~S\ has\ not\ been\ defined.=
+
+#: defstruct.lisp:593
+!~S\ ~S\:\ included\ structure\ ~S\ must\ be\ of\ the\ same\ type\ ~S.=
+
+#: defstruct.lisp:618
+!~S\ ~S\:\ included\ structure\ ~S\ has\ no\ component\ with\ name\ ~S.=
+
+#: defstruct.lisp:647
+!~S\ ~S\:\ The\ READ-ONLY\ slot\ ~S\ of\ the\ included\ structure\ ~S\ must\ remain\ READ-ONLY\ in\ ~S.=
+
+#: defstruct.lisp:657
+!~S\ ~S\:\ The\ type\ ~S\ of\ slot\ ~S\ should\ be\ a\ subtype\ of\ the\ type\ defined\ for\ the\ included\ strucure\ ~S,\ namely\ ~S.=
+
+#: defstruct.lisp:663 defstruct.lisp:761
+!~S\ ~S\:\ ~S\ is\ not\ a\ slot\ option.=
+
+#: defstruct.lisp:695
+!~S\ ~S\:\ structure\ of\ type\ ~S\ can't\ hold\ the\ name.=
+
+#: defstruct.lisp:747
+!~S\ ~S\:\ There\ may\ be\ only\ one\ slot\ with\ the\ name\ ~S.=
+
+#: format.lisp:70
+!The\ control\ string\ terminates\ within\ a\ directive.=
+
+#: format.lisp:137
+!~A\ must\ introduce\ a\ number.=
+
+#: format.lisp:147
+!The\ control\ string\ terminates\ in\ the\ middle\ of\ a\ parameter.=
+
+#: format.lisp:227
+!Non-existent\ directive=
+
+#: format.lisp:235
+!Closing\ '/'\ is\ missing=
+
+#: format.lisp:248
+!There\ is\ no\ package\ with\ name\ ~S=
+
+#: format.lisp:263
+!The\ closing\ directive\ '~A'\ does\ not\ have\ a\ corresponding\ opening\ one.=
+
+#: format.lisp:268
+!The\ closing\ directive\ '~A'\ does\ not\ match\ the\ corresponding\ opening\ one.\ It\ should\ read\ '~A'.=
+
+#: format.lisp:277 format.lisp:1641 format.lisp:2445
+!The\ ~~;\ directive\ is\ not\ allowed\ at\ this\ point.=
+
+#: format.lisp:287
+!The\ ~~newline\ directive\ cannot\ take\ both\ modifiers.=
+
+#: format.lisp:308
+!An\ opening\ directive\ is\ never\ closed;\ expecting\ '~A'.=
+
+#: format.lisp:333
+!~%Current\ point\ in\ control\ string\:=
+
+#: format.lisp:383
+!The\ destination\ string\ ~S\ should\ have\ a\ fill\ pointer.=
+
+#: format.lisp:390
+!The\ destination\ argument\ ~S\ is\ invalid\ (not\ NIL\ or\ T\ or\ a\ stream\ or\ a\ string).=
+
+#: format.lisp:419
+!~S\:\ The\ control-string\ must\ be\ a\ string,\ not\ ~S=
+
+#: format.lisp:430
+!There\ are\ not\ enough\ arguments\ left\ for\ this\ directive.=
+
+#: format.lisp:528
+!The\ ~~\:@R\ directive\ requires\ an\ integer\ in\ the\ range\ 1\ -\ 4999,\ not\ ~S=
+
+#: format.lisp:547
+!The\ ~~@R\ directive\ requires\ an\ integer\ in\ the\ range\ 1\ -\ 3999,\ not\ ~S=
+
+#: format.lisp:611
+!The\ argument\ for\ the\ ~~R\ directive\ is\ too\ large.=
+
+#: format.lisp:1331
+!The\ ~~R\ and\ ~~\:R\ directives\ require\ an\ integer\ argument,\ not\ ~S=
+
+#: format.lisp:1353
+!The\ ~~C\ directive\ requires\ a\ character\ argument,\ not\ ~S=
+
+#: format.lisp:1579
+!The\ control\ string\ argument\ for\ the\ ~~?\ directive\ is\ invalid\:\ ~S=
+
+#: format.lisp:1584
+!The\ argument\ list\ argument\ for\ the\ ~~?\ directive\ is\ invalid\:\ ~S=
+
+#: format.lisp:1646
+!The\ ~~[\ parameter\ must\ be\ an\ integer,\ not\ ~S=
+
+#: format.lisp:1665
+!The\ ~~[\ directive\ cannot\ take\ both\ modifiers.=
+
+#: format.lisp:1691
+!The\ ~~{\ directive\ requires\ a\ list\ argument,\ not\ ~S=
+
+#: format.lisp:2179
+!Too\ many\ arguments\ for\ this\ directive=
+
+#: format.lisp:2718
+!The\ control-string\ must\ be\ a\ string,\ not\ ~S=
+
+#: trace.lisp:85 trace.lisp:253
+!~S\:\ function\ name\ should\ be\ a\ symbol,\ not\ ~S=
+
+#: trace.lisp:95
+!~S\:\ undefined\ function\ ~S=
+
+#: trace.lisp:101
+!~S\:\ cannot\ trace\ special\ operator\ ~S=
+
+#: trace.lisp:112
+!~&;;\ Tracing\ ~\:[function~;macro~]\ ~S.=
+
+#: trace.lisp:266
+!~S\:\ ~S\ was\ traced\ and\ has\ been\ redefined\!=
+
+#: compiler.lisp:226
+!~1{~5@*~D/~4@*~D/~3@*~D\ ~2@*~2,'0D.~1@*~2,'0D.~0@*~2,'0D~\:}=
+
+#: compiler.lisp:387
+!Bad\ length\ of\ closure\ vector\:\ ~S=
+
+#: compiler.lisp:1783
+!Compiler\ bug\!\!\ Occurred\ in\ ~A~@[\ at\ ~A~].=
+
+#: compiler.lisp:2488
+!Bad\ declaration\ syntax\:\ ~S~%Will\ be\ ignored.=
+
+#: compiler.lisp:2508
+!Non-symbol\ ~S\ may\ not\ be\ declared\ SPECIAL.=
+
+#: compiler.lisp:2515
+!Non-symbol\ ~S\ may\ not\ be\ declared\ IGNORE.=
+
+#: compiler.lisp:2522
+!Non-symbol\ ~S\ may\ not\ be\ declared\ IGNORABLE.=
+
+#: compiler.lisp:2529
+!Non-symbol\ ~S\ may\ not\ be\ declared\ READ-ONLY.=
+
+#: compiler.lisp:2534
+!Unknown\ declaration\ ~S.~%The\ whole\ declaration\ will\ be\ ignored.=
+
+#: compiler.lisp:2924
+!\ in\ line\ ~D=
+
+#: compiler.lisp:2925
+!\ in\ lines\ ~D..~D=
+
+#: compiler.lisp:2937
+!~%WARNING~@[\ in\ function\ ~S~]~A\ \:~%=
+
+#: compiler.lisp:2969
+!~%ERROR~@[\ in\ function\ ~S~]~A\ \:~%~?=
+
+#: compiler.lisp:3110
+!Code\ contains\ dotted\ list\ ~S=
+
+#: compiler.lisp:3114
+!Form\ too\ short,\ too\ few\ arguments\:\ ~S=
+
+#: compiler.lisp:3119
+!Form\ too\ long,\ too\ many\ arguments\:\ ~S=
+
+#: compiler.lisp:3301
+!Not\ the\ name\ of\ a\ function\:\ ~S=
+
+#: compiler.lisp:3382 compiler.lisp:3458
+!~S\ is\ neither\ declared\ nor\ bound,~@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ it\ will\ be\ treated\ as\ if\ it\ were\ declared\ SPECIAL.=
+
+#: compiler.lisp:3475
+!The\ constant\ ~S\ may\ not\ be\ assigned\ to.~@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ The\ assignment\ will\ be\ ignored.=
+
+#: compiler.lisp:3614
+!argument\ list\ to\ function\ ~S\ is\ dotted\:\ ~S=
+
+#: compiler.lisp:3620
+!~S\ called\ with\ ~S~\:[~;\ or\ more~]\ arguments,\ but\ it\ requires\ ~\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ~\:[~\:[from\ ~S\ to\ ~S~;~S~]~;at\ least\ ~*~S~]\ arguments.=
+
+#: compiler.lisp:3633
+!keyword\ arguments\ to\ function\ ~S\ should\ occur\ pairwise\:\ ~S=
+
+#: compiler.lisp:3644
+!keyword\ ~S\ is\ not\ allowed\ for\ function\ ~S.~\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ~%The\ only\ allowed\ keyword~\:[s\ are\ ~{~S~\#[~;\ and\ ~S~\:;,\ ~]~}~;\ is\ ~{~S~}~].=
+
+#: compiler.lisp:3656
+!argument\ ~S\ to\ function\ ~S\ is\ not\ a\ symbol=
+
+#: compiler.lisp:4325
+!~S\ called\ with\ ~S\ arguments,\ but\ it\ requires\ ~\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ~\:[~\:[from\ ~S\ to\ ~S~;~S~]~;at\ least\ ~*~S~]\ arguments.=
+
+#: compiler.lisp:4505
+!Illegal\ syntax\ in\ LET/LET*\:\ ~S=
+
+#: compiler.lisp:4542
+!Lambda\ list\ marker\ ~S\ not\ allowed\ here.=
+
+#: compiler.lisp:4548
+!Missing\ &REST\ parameter\ in\ lambda\ list\ ~S=
+
+#: compiler.lisp:4554
+!Lambda\ list\ element\ ~S\ is\ superfluous.=
+
+#: compiler.lisp:4729
+!Lambda\ lists\ with\ dots\ are\ only\ allowed\ in\ macros,\ not\ here\:\ ~S=
+
+#: compiler.lisp:4745
+!Illegal\ lambda\ list\ element\ ~S=
+
+#: compiler.lisp:4841
+!Binding\ variable\ ~S\ can\ cause\ side\ effects\ despite\ of\ IGNORE\ declaration~%since\ it\ is\ declared\ SPECIAL.=
+
+#: compiler.lisp:4845
+!variable\ ~S\ is\ used\ despite\ of\ IGNORE\ declaration.=
+
+#: compiler.lisp:4856
+!variable\ ~S\ is\ not\ used.~%Misspelled\ or\ missing\ IGNORE\ declaration?=
+
+#: compiler.lisp:4862
+!The\ variable\ ~S\ is\ assigned\ to,\ despite\ of\ READ-ONLY\ declaration.=
+
+#: compiler.lisp:4908 compiler.lisp:5044
+!Constant\ ~S\ cannot\ be\ bound.=
+
+#: compiler.lisp:5806
+!Misplaced\ declaration\:\ ~S=
+
+#: compiler.lisp:6018
+!Odd\ number\ of\ arguments\ to\ SETQ\:\ ~S=
+
+#: compiler.lisp:6055 compiler.lisp:6092 compiler.lisp:6190
+!Cannot\ assign\ to\ non-symbol\ ~S.=
+
+#: compiler.lisp:6067
+!Odd\ number\ of\ arguments\ to\ PSETQ\:\ ~S=
+
+#: compiler.lisp:6328
+!Only\ symbols\ may\ be\ used\ as\ variables,\ not\ ~S=
+
+#: compiler.lisp:6433
+!Illegal\ syntax\ in\ COMPILER-LET\:\ ~S=
+
+#: compiler.lisp:6441
+!Block\ name\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: compiler.lisp:6490
+!RETURN-FROM\ block\ ~S\ is\ impossible\ from\ here.=
+
+#: compiler.lisp:6556
+!Only\ numbers\ and\ symbols\ are\ valid\ tags,\ not\ ~S=
+
+#: compiler.lisp:6634
+!Tag\ must\ be\ a\ symbol\ or\ a\ number,\ not\ ~S=
+
+#: compiler.lisp:6639
+!GO\ to\ tag\ ~S\ is\ impossible\ from\ here.=
+
+#: compiler.lisp:6730
+!~S\ is\ not\ a\ function.\ It\ is\ a\ locally\ defined\ macro.=
+
+#: compiler.lisp:6749
+!Only\ symbols\ and\ lambda\ expressions\ are\ function\ names,\ not\ ~S=
+
+#: compiler.lisp:6804
+!Illegal\ function\ definition\ syntax\ in\ ~S\:\ ~S=
+
+#: compiler.lisp:7377
+!Illegal\ syntax\ in\ SYMBOL-MACROLET\:\ ~S=
+
+#: compiler.lisp:7418
+!EVAL-WHEN\ situation\ must\ be\ EVAL\ or\ LOAD\ or\ COMPILE,\ but\ not\ ~S=
+
+#: compiler.lisp:7461
+!CASE\ clause\ without\ objects\:\ ~S=
+
+#: compiler.lisp:7471
+!~S\:\ the\ ~S\ clause\ must\ be\ the\ last\ one\:\ ~S=
+
+#: compiler.lisp:7481
+!Duplicate\ ~S\ label\ ~S\ \:\ ~S=
+
+#: compiler.lisp:7743
+!Too\ many\ arguments\ to\ ~S=
+
+#: compiler.lisp:7758
+!Too\ few\ arguments\ to\ ~S=
+
+#: compiler.lisp:8649
+!The\ ~S\ destination\ is\ invalid\ (not\ NIL\ or\ T\ or\ a\ stream\ or\ a\ string\ with\ fill-pointer)\:\ ~S=
+
+#: compiler.lisp:12137
+!Name\ of\ function\ to\ be\ compiled\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: compiler.lisp:12148
+!~S\:\ redefining\ ~S;\ it\ was\ traced\!=
+
+#: compiler.lisp:12156 compiler.lisp:12189
+!~S\ is\ already\ compiled.=
+
+#: compiler.lisp:12177 compiler.lisp:12819
+!Undefined\ function\ ~S=
+
+#: compiler.lisp:12198
+!Not\ a\ lambda\ expression\ nor\ a\ function\:\ ~S=
+
+#: compiler.lisp:12384
+!~%There\ were\ errors\ in\ the\ following\ functions\:~%~{~<~%~\:;\ ~S~>~^~}=
+
+#: compiler.lisp:12389
+!~%The\ following\ functions\ were\ used\ but\ not\ defined\:~%~{~<~%~\:;\ ~S~>~^~}=
+
+#: compiler.lisp:12396
+!~%The\ following\ special\ variables\ were\ not\ defined\:~%~{~<~%~\:;\ ~S~>~^~}=
+
+#: compiler.lisp:12399
+!~%The\ following\ special\ variables\ were\ defined\ too\ late\:~%~{~<~%~\:;\ ~S~>~^~}=
+
+#: compiler.lisp:12402
+!~%The\ following\ functions\ were\ used\ but\ are\ deprecated\:~%~{~<~%~\:;\ ~S~>~^~}=
+
+#: compiler.lisp:12529
+!~&Listing\ of\ compilation\ of\ file\ ~A~%on\ ~@?\ by\ ~A,\ version\ ~A=
+
+#: compiler.lisp:12561
+!~%Compiling\ file\ ~A\ ...=
+
+#: compiler.lisp:12611
+!~&~%Compilation\ of\ file\ ~A\ is\ finished.=
+
+#: compiler.lisp:12613
+!~%~D\ error~\:P,\ ~D\ warning~\:P=
+
+#: compiler.lisp:12663
+!~%~%Disassembly\ of\ function\ ~S=
+
+#: compiler.lisp:12674
+!~%~S\ required\ arguments=
+
+#: compiler.lisp:12677
+!~%~S\ optional\ arguments=
+
+#: compiler.lisp:12680
+!~%~\:[No\ rest\ parameter~;Rest\ parameter~]=
+
+#: compiler.lisp:12685
+!~%~S\ keyword\ parameter~\:P\:\ ~{~S~^,\ ~}.=
+
+#: compiler.lisp:12689
+!~%Other\ keywords\ are\ allowed.=
+
+#: compiler.lisp:12691
+!~%No\ keyword\ parameters=
+
+#: compiler.lisp:12708
+!Disassembly\ of\ function\ =
+
+#: compiler.lisp:12726
+!\ required\ arguments=
+
+#: compiler.lisp:12731
+!\ optional\ arguments=
+
+#: compiler.lisp:12736
+!Rest\ parameter=
+
+#: compiler.lisp:12739
+!No\ rest\ parameter=
+
+#: compiler.lisp:12746
+!\ keyword\ parameter~P\:\ =
+
+#: compiler.lisp:12756
+!Other\ keywords\ are\ allowed.=
+
+#: compiler.lisp:12761
+!No\ keyword\ parameters=
+
+#: compiler.lisp:12842
+!Cannot\ disassemble\ ~S=
+
+#: defs2.lisp:63
+!~S\:\ ~S\ is\ not\ a\ function=
+
+#: defs2.lisp:77
+!~S\:\ package\ name\ ~S\ should\ be\ a\ string\ or\ a\ symbol=
+
+#: defs2.lisp:84
+!~S\ ~A\:\ symbol\ name\ ~S\ should\ be\ a\ string\ or\ a\ symbol=
+
+#: defs2.lisp:104
+!~S\ ~A\:\ the\ symbol\ ~A\ must\ not\ be\ specified\ more\ than\ once=
+
+#: defs2.lisp:116 defs2.lisp:124
+!~S\ ~A\:\ the\ ~S\ option\ must\ not\ be\ given\ more\ than\ once=
+
+#: defs2.lisp:182
+!~S\ ~A\:\ unknown\ option\ ~S=
+
+#: defs2.lisp:186
+!~S\ ~A\:\ invalid\ syntax\ in\ ~S\ option\:\ ~S=
+
+#: defs2.lisp:190
+!~S\ ~A\:\ not\ a\ ~S\ option\:\ ~S=
+
+#: defs2.lisp:246
+!This\ symbol\ will\ be\ created.=
+
+#: defs2.lisp:247
+!~S\ ~A\:\ There\ is\ no\ symbol\ ~A\:\:~A\ .=
+
+#: defs2.lisp:321
+!The\ object\ to\ be\ destructured\ should\ be\ a\ list\ with\ ~\:[at\ least\ ~*~S~;~\:[from\ ~S\ to\ ~S~;~S~]~]\ elements,\ not\ ~4@*~S.=
+
+#: defs2.lisp:390
+!~S\:\ macro\ name\ should\ be\ a\ symbol,\ not\ ~S=
+
+#: defs2.lisp:425
+!~S\:\ input\ stream\ ~S\ ends\ within\ read\ macro\ beginning\ to\ ~S=
+
+#: defs2.lisp:431
+!~S\ from\ ~S\:\ character\ read\ should\ be\ a\ character\:\ ~S=
+
+#: defs2.lisp:452
+!~S\ from\ ~S\:\ After\ ~S\ is\ ~S\ an\ undefined\ dispatch\ macro\ character=
+
+#: defs2.lisp:518 defs2.lisp:533
+!~S\:\ ~S\ of\ ~S\ is\ ambiguous.\ Please\ use\ ~S\ or\ ~S.=
+
+#: loop.lisp:47
+!~S\:\ syntax\ error\ after\ ~A\ in\ ~S=
+
+#: loop.lisp:254
+!~S\:\ missing\ variable.=
+
+#: loop.lisp:264
+!~S\:\ After\ ~S,\ ~S\ is\ interpreted\ as\ a\ type\ specification=
+
+#: loop.lisp:520
+!~S\:\ ~A\ clauses\ should\ occur\ before\ the\ loop's\ main\ body=
+
+#: loop.lisp:660
+!~S\:\ After\ ~S\ a\ plural\ loop\ keyword\ is\ required,\ not\ ~A=
+
+#: loop.lisp:665
+!~S\:\ After\ ~S\ a\ singular\ loop\ keyword\ is\ required,\ not\ ~A=
+
+#: loop.lisp:807
+!~S\:\ questionable\ iteration\ direction\ after\ ~A=
+
+#: loop.lisp:816
+!~S\:\ specifying\ ~A\ requires\ FROM\ or\ DOWNFROM=
+
+#: loop.lisp:874
+!~S\:\ illegal\ syntax\ near\ ~S\ in\ ~S=
+
+#: loop.lisp:879
+!~S\:\ ambiguous\ result\ of\ loop\ ~S=
+
+#: loop.lisp:1012
+!~S\ is\ possible\ only\ from\ within\ ~S=
+
+#: loop.lisp:1015
+!Use\ of\ ~S\ in\ FINALLY\ clauses\ is\ deprecated\ because\ it\ can\ lead\ to\ infinite\ loops.=
+
+#: loop.lisp:1018
+!~S\ is\ not\ possible\ here=
+
+#: clos.lisp:167 clos.lisp:188
+!~S\:\ argument\ ~S\ is\ not\ a\ symbol=
+
+#: clos.lisp:174
+!~S\:\ ~S\ does\ not\ name\ a\ class=
+
+#: clos.lisp:194
+!~S\:\ ~S\ is\ not\ a\ class=
+
+#: clos.lisp:201
+!~S\:\ cannot\ redefine\ built-in\ class\ ~S=
+
+#: clos.lisp:206
+!~S\:\ Redefining\ the\ COMMON\ LISP\ class\ ~S=
+
+#: clos.lisp:361
+!instance\ ~S\ of\ class\ ~S\ has\ no\ slots\ (wrong\ metaclass)=
+
+#: clos.lisp:382 clos.lisp:427
+!~S\:\ not\ a\ list\ of\ slots\:\ ~S=
+
+#: clos.lisp:390
+!~S\:\ invalid\ slot\ and\ variable\ specification\ ~S=
+
+#: clos.lisp:396 clos.lisp:438
+!~S\:\ variable\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:402
+!~S\:\ slot\ name\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:433
+!~S\:\ invalid\ slot\ and\ accessor\ specification\ ~S=
+
+#: clos.lisp:443
+!~S\:\ accessor\ name\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:534
+!~S\:\ class\ name\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:541
+!~S\ ~S\:\ expecting\ list\ of\ superclasses\ instead\ of\ ~S=
+
+#: clos.lisp:547
+!~S\ ~S\:\ superclass\ name\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:559
+!~S\ ~S\:\ expecting\ list\ of\ slot\ specifications\ instead\ of\ ~S=
+
+#: clos.lisp:569
+!~S\ ~S\:\ slot\ name\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:574
+!~S\ ~S\:\ There\ may\ be\ only\ one\ direct\ slot\ with\ the\ name\ ~S.=
+
+#: clos.lisp:589
+!~S\ ~S\:\ slot\ options\ for\ slot\ ~S\ don't\ come\ in\ pairs=
+
+#: clos.lisp:600
+!~S\ ~S,\ slot\ option\ for\ slot\ ~S\:\ ~S\ is\ not\ a\ function\ name=
+
+#: clos.lisp:610 clos.lisp:632
+!~S\ ~S,\ slot\ option\ for\ slot\ ~S\:\ ~S\ is\ not\ a\ symbol=
+
+#: clos.lisp:620 clos.lisp:640 clos.lisp:649 clos.lisp:657
+!~S\ ~S,\ slot\ option\ ~S\ for\ slot\ ~S\ may\ only\ be\ given\ once=
+
+#: clos.lisp:626
+!~S\ ~S,\ slot\ option\ for\ slot\ ~S\ must\ have\ the\ value\ ~S\ or\ ~S,\ not\ ~S=
+
+#: clos.lisp:662
+!~S\ ~S,\ slot\ option\ for\ slot\ ~S\:\ ~S\ is\ not\ a\ string=
+
+#: clos.lisp:669
+!~S\ ~S,\ slot\ option\ for\ slot\ ~S\:\ ~S\ is\ not\ a\ valid\ slot\ option=
+
+#: clos.lisp:720
+!~S\ ~S,\ option\ ~S\ may\ only\ be\ given\ once=
+
+#: clos.lisp:729 clos.lisp:756
+!~S\ ~S,\ option\ ~S\:\ ~S\ is\ not\ a\ symbol=
+
+#: clos.lisp:740
+!~S\ ~S\:\ option\ ~S\ should\ be\ written\ ~S=
+
+#: clos.lisp:745
+!~S\ ~S,\ option\ ~S\:\ arguments\ don't\ come\ in\ pairs=
+
+#: clos.lisp:761
+!~S\ ~S,\ option\ ~S\:\ ~S\ may\ only\ be\ given\ once=
+
+#: clos.lisp:781
+!~S\ ~S,\ option\ ~S\:\ ~S\ is\ not\ a\ string=
+
+#: clos.lisp:790
+!~S\ ~S\:\ invalid\ option\ ~S=
+
+#: clos.lisp:897
+!~S\:\ Class\ ~S\ is\ being\ redefined,\ instances\ are\ obsolete=
+
+#: clos.lisp:984
+!~S\ ~S\:\ superclass\ ~S\ should\ belong\ to\ class\ STANDARD-CLASS=
+
+#: clos.lisp:1154
+!~S\ ~S\:\ inconsistent\ precedence\ graph,\ cycle\ ~S=
+
+#: clos.lisp:1193
+!(class-precedence-list\ ~S)\ and\ (class-precedence-list\ ~S)\ are\ inconsistent=
+
+#: clos.lisp:1350
+!~S\:\ superclass\ ~S\ should\ belong\ to\ class\ BUILT-IN-CLASS=
+
+#: clos.lisp:1392
+!~S\:\ metaclass\ STRUCTURE-CLASS\ forbids\ more\ than\ one\ direct\ superclass=
+
+#: clos.lisp:1398
+!~S\:\ superclass\ ~S\ should\ belong\ to\ class\ STRUCTURE-CLASS=
+
+#: clos.lisp:1438
+!~S\:\ metaclass\ STRUCTURE-CLASS\ does\ not\ support\ shared\ slots=
+
+#: clos.lisp:1711
+!~S\ ~S\:\ missing\ lambda\ list=
+
+#: clos.lisp:1723
+!STANDARD\ method\ combination\ doesn't\ allow\ the\ method\ qualifiers\ to\ be\ ~S=
+
+#: clos.lisp:1906 clos.lisp:1912
+!~S\ ~S\:\ ~S\ is\ invalid\ within\ ~S\ methods=
+
+#: clos.lisp:2168
+!Too\ few\ arguments\ to\ ~S\:\ ~S=
+
+#: clos.lisp:2297
+!The\ generic\ function\ ~S\ is\ being\ modified,\ but\ has\ already\ been\ called.=
+
+#: clos.lisp:2856
+!~S\ in\ ~S\:\ the\ new\ arguments\ ~S\ have\ a\ different\ effective\ method\ than\ the\ old\ arguments\ ~S=
+
+#: clos.lisp:2881
+!~S\ has\ ~S,\ but\ ~S\ has\ ~S\ required\ parameters=
+
+#: clos.lisp:2886
+!~S\ has\ ~S,\ but\ ~S\ has\ ~S\ optional\ parameters=
+
+#: clos.lisp:2891 clos.lisp:2896
+!~S\ has\ &REST\ or\ &KEY,\ but\ ~S\ hasn't.=
+
+#: clos.lisp:2908
+!~S\ doesn't\ accept\ the\ keywords\ ~S\ of\ ~S=
+
+#: clos.lisp:2938
+!Replacing\ method\ ~S\ in\ ~S=
+
+#: clos.lisp:2956
+!Removing\ method\ ~S\ in\ ~S=
+
+#: clos.lisp:2984
+!~S\ has\ no\ method\ with\ qualifiers\ ~\:S\ and\ specializers\ ~S=
+
+#: clos.lisp:3013 clos.lisp:3320
+!~S\ doesn't\ name\ a\ generic\ function=
+
+#: clos.lisp:3075
+!~S\ ~S\:\ Only\ ~S\ declarations\ are\ permitted\:\ ~S=
+
+#: clos.lisp:3084
+!~S\ ~S\:\ ~S\ may\ only\ be\ specified\ once.=
+
+#: clos.lisp:3092
+!~S\ ~S\:\ A\ string\ must\ be\ specified\ after\ ~S\ \:\ ~S=
+
+#: clos.lisp:3097
+!~S\ ~S\:\ Only\ one\ ~S\ string\ is\ allowed=
+
+#: clos.lisp:3105
+!~S\ ~S\:\ The\ only\ valid\ method\ combination\ is\ ~S\ \:\ ~S=
+
+#: clos.lisp:3113
+!~S\ ~S\:\ The\ only\ valid\ generic\ function\ class\ name\ is\ ~S\ \:\ ~S=
+
+#: clos.lisp:3121
+!~S\ ~S\:\ The\ only\ valid\ method\ class\ name\ is\ ~S\ \:\ ~S=
+
+#: clos.lisp:3140
+!~S\ ~S\:\ ~S\ is\ not\ one\ of\ the\ required\ parameters\:\ ~S=
+
+#: clos.lisp:3152
+!~S\ ~S\:\ some\ variable\ occurs\ twice\ in\ ~S=
+
+#: clos.lisp:3157
+!~S\ ~S\:\ ~S\ is\ missing\ some\ required\ parameter=
+
+#: clos.lisp:3186
+!~S\ ~S\:\ No\ initializations\ are\ allowed\ in\ a\ generic\ function\ lambda-list\:\ ~S=
+
+#: clos.lisp:3192
+!~S\ ~S\:\ variable\ name\ ~S\ should\ be\ a\ symbol=
+
+#: clos.lisp:3197
+!~S\ ~S\:\ duplicate\ variable\ name\ ~S=
+
+#: clos.lisp:3248
+!~S\ ~S\:\ invalid\ lambda\ list\ portion\:\ ~S=
+
+#: clos.lisp:3301
+!Removing\ all\ methods\ of\ ~S=
+
+#: clos.lisp:3309
+!Modifying\ the\ parameter\ profile\ of\ ~S=
+
+#: clos.lisp:3365
+!~S\:\ ~S\ is\ not\ a\ generic\ function\ specification=
+
+#: clos.lisp:3428
+!~S\:\ The\ name\ of\ a\ class\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: clos.lisp:3433
+!~S\:\ The\ name\ of\ the\ built-in\ class\ ~S\ cannot\ be\ modified=
+
+#: clos.lisp:3476 clos.lisp:3480
+!~S\:\ When\ calling\ ~S\ with\ arguments\ ~S,\ no\ method\ is\ applicable.=
+
+#: clos.lisp:3498 clos.lisp:3502
+!~S\:\ When\ calling\ ~S\ with\ arguments\ ~S,\ no\ primary\ method\ is\ applicable.=
+
+#: clos.lisp:3512
+!~S\:\ When\ calling\ ~S\ with\ arguments\ ~S,\ there\ is\ no\ next\ method\ after\ ~S,\ and\ ~S\ was\ called.=
+
+#: clos.lisp:3563
+!~S\:\ The\ class\ ~S\ has\ no\ slot\ named\ ~S=
+
+#: clos.lisp:3573
+!~S\:\ The\ slot\ ~S\ of\ ~S\ has\ no\ value=
+
+#: clos.lisp:4082
+!~S\ method\ for\ ~S\ returned\ ~S=
+
+#: condition.lisp:80
+!~S\:\ the\ name\ of\ a\ condition\ must\ be\ a\ symbol,\ not\ ~S=
+
+#: condition.lisp:85
+!~S\:\ the\ parent-type\ list\ must\ be\ a\ list\ of\ symbols,\ not\ ~S=
+
+#: condition.lisp:90
+!~S\:\ the\ slot\ description\ list\ must\ be\ a\ list,\ not\ ~S=
+
+#: condition.lisp:145
+!~S\:\ type\ ~S\ is\ not\ a\ subtype\ of\ ~S=
+
+#: condition.lisp:161
+!~S\ ~S\:\ superfluous\ arguments\ ~S=
+
+#: condition.lisp:178
+!~S\:\ the\ condition\ argument\ must\ be\ a\ string,\ a\ symbol\ or\ a\ condition,\ not\ ~S=
+
+#: condition.lisp:579
+!~S\:\ illegal\ syntax\ of\ clause\ ~S=
+
+#: condition.lisp:586
+!~S\:\ only\ one\ ~S\ clause\ is\ allowed\:\ ~S=
+
+#: condition.lisp:594
+!~S\:\ too\ many\ variables\ ~S\ in\ clause\ ~S=
+
+#: condition.lisp:807
+!~S\:\ ~S\ is\ not\ a\ valid\ restart\ name\ here.\ Use\ ~S\ instead.=
+
+#: condition.lisp:828
+!~S\:\ invalid\ restart\ name\ ~S=
+
+#: condition.lisp:835
+!~S\:\ No\ restart\ named\ ~S\ is\ visible.=
+
+#: condition.lisp:893 condition.lisp:952
+!~S\:\ not\ a\ list\:\ ~S=
+
+#: condition.lisp:902 condition.lisp:961
+!~S\:\ invalid\ restart\ specification\ ~S=
+
+#: condition.lisp:913 condition.lisp:999
+!~S\:\ unnamed\ restarts\ require\ ~S\ to\ be\ specified\:\ ~S=
+
+#: condition.lisp:984
+!~S\:\ missing\ lambda\ list\ in\ restart\ specification\ ~S=
+
+#: condition.lisp:1007
+!~S\:\ restart\ cannot\ be\ invoked\ interactively\ because\ it\ is\ missing\ a\ ~S\ option\:\ ~S=
+
+#: condition.lisp:1206
+!~%New\ ~S\ [value\ ~D\ of\ ~D]\:\ =
+
+#: condition.lisp:1425 condition.lisp:1541
+!Return\ from\ ~S\ loop=
+
+#: condition.lisp:1509 condition.lisp:1532
+!WARNING\:=
+
+#: condition.lisp:1521
+!~S\:\ This\ is\ more\ serious\ than\ a\ warning\:\ ~A=
+
+#: xcharin.lisp:36
+!~\:\ argument\ ~S\ is\ not\ a\ character=
+
+#: xcharin.lisp:57
+!~S\:\ the\ font\ argument\ should\ be\ an\ integer,\ not\ ~S=
+
+#: xcharin.lisp:66
+!~S\:\ the\ bits\ argument\ should\ be\ an\ integer,\ not\ ~S=
+
+#: xcharin.lisp:88
+!~S\:\ the\ only\ bit\ names\ are\ ~S,\ ~S,\ ~S,\ ~S,\ not\ ~S=
+
+#: screen.lisp:227
+!Got\ bad\ response\ from\ ~S\:\ ~S=
+
+#: amigasock.lisp:30
+!~S\:\ ~S\ is\ not\ a\ SOCKET-SERVER=
+
+#: beossock.lisp:77 beossock.lisp:87
+!service\ does\ not\ exist\:\ ~A/~A=
+
+#: runprog.lisp:162
+!~S\:\ File\ ~S\ already\ exists=
+
+#: query.lisp:12
+!\ (y/n)\ =
+
+#: query.lisp:23
+!Please\ answer\ with\ y\ or\ n\ \:\ =
+
+#: query.lisp:33
+!\ (yes/no)\ =
+
+#: query.lisp:43
+!Please\ answer\ with\ yes\ or\ no\ \:\ =
+
+#: reploop.lisp:60
+![*package*\ invalid]=
+
+#: reploop.lisp:193
+!Values\:\ =
+
+#: reploop.lisp:210
+!\nHelp\ (abbreviated\ \:h)\ \=\ this\ list\nUse\ the\ usual\ editing\ capabilities.\n(quit)\ or\ (exit)\ leaves\ CLISP.=
+
+#: reploop.lisp:220
+!\nCommands\ may\ be\ abbreviated\ as\ shown\ in\ the\ second\ column.\nCOMMAND\ \ \ \ \ \ \ \ ABBR\ \ \ \ \ \ \ \ \ \ \ \ \ DESCRIPTION\nHelp\ \ \ \ \ \ \ \ \ \ \ \:h\ (or\ ?)\ \ \ \ \ \ \ \ this\ command\ list\nError\ \ \ \ \ \ \ \ \ \ \:e\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Print\ the\ recent\ Error\ Message\nAbort\ \ \ \ \ \ \ \ \ \ \:a\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ abort\ to\ the\ next\ recent\ input\ loop\nUnwind\ \ \ \ \ \ \ \ \ \:uw\ \ \ \ \ \ \ \ \ \ \ \ \ \ abort\ to\ the\ next\ recent\ input\ loop\nMode-1\ \ \ \ \ \ \ \ \ \:m1\ \ \ \ \ \ \ \ \ \ \ \ \ \ inspect\ all\ the\ stack\ elements\nMode-2\ \ \ \ \ \ \ \ \ \:m2\ \ \ \ \ \ \ \ \ \ \ \ \ \ inspect\ all\ the\ frames\nMode-3\ \ \ \ \ \ \ \ \ \:m3\ \ \ \ \ \ \ \ \ \ \ \ \ \ inspect\ only\ lexical\ frames\nMode-4\ \ \ \ \ \ \ \ \ \:m4\ \ \ \ \ \ \ \ \ \ \ \ \ \ inspect\ only\ EVAL\ and\ APPLY\ frames\ (default)\nMode-5\ \ \ \ \ \ \ \ \ \:m5\ \ \ \ \ \ \ \ \ \ \ \ \ \ inspect\ only\ APPLY\ frames\nWhere\ \ \ \ \ \ \ \ \ \ \:w\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ inspect\ this\ frame\nUp\ \ \ \ \ \ \ \ \ \ \ \ \ \:u\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ go\ up\ one\ frame,\ inspect\ it\nTop\ \ \ \ \ \ \ \ \ \ \ \ \:t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ go\ to\ top\ frame,\ inspect\ it\nDown\ \ \ \ \ \ \ \ \ \ \ \:d\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ go\ down\ one\ frame,\ inspect\ it\nBottom\ \ \ \ \ \ \ \ \ \:b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ go\ to\ bottom\ (most\ recent)\ frame,\ inspect\ it\nBacktrace-1\ \ \ \ \:bt1\ \ \ \ \ \ \ \ \ \ \ \ \ list\ all\ stack\ elements\nBacktrace-2\ \ \ \ \:bt2\ \ \ \ \ \ \ \ \ \ \ \ \ list\ all\ frames\nBacktrace-3\ \ \ \ \:bt3\ \ \ \ \ \ \ \ \ \ \ \ \ list\ all\ lexical\ frames\nBacktrace-4\ \ \ \ \:bt4\ \ \ \ \ \ \ \ \ \ \ \ \ list\ all\ EVAL\ and\ APPLY\ frames\nBacktrace-5\ \ \ \ \:bt5\ \ \ \ \ \ \ \ \ \ \ \ \ list\ all\ APPLY\ frames\nBacktrace\ \ \ \ \ \ \:bt\ \ \ \ \ \ \ \ \ \ \ \ \ \ list\ stack\ in\ current\ mode\nBacktrace-l\ \ \ \ \:bl\ \ \ \ \ \ \ \ \ \ \ \ \ \ list\ stack\ in\ current\ mode.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Limit\ of\ frames\ to\ print\ will\ be\ prompted\ for.\nFrame-limit\ \ \ \ \:fl\ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ the\ frame-limit.\ This\ many\ frames\ will\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ be\ printed\ in\ a\ backtrace\ at\ most.\nBreak+\ \ \ \ \ \ \ \ \ \:br+\ \ \ \ \ \ \ \ \ \ \ \ \ set\ breakpoint\ in\ EVAL\ frame\nBreak-\ \ \ \ \ \ \ \ \ \:br-\ \ \ \ \ \ \ \ \ \ \ \ \ disable\ breakpoint\ in\ EVAL\ frame\nRedo\ \ \ \ \ \ \ \ \ \ \ \:rd\ \ \ \ \ \ \ \ \ \ \ \ \ \ re-evaluate\ form\ in\ EVAL\ frame\nReturn\ \ \ \ \ \ \ \ \ \:rt\ \ \ \ \ \ \ \ \ \ \ \ \ \ leave\ EVAL\ frame,\ prescribing\ the\ return\ values=
+
+#: reploop.lisp:310
+!\nContinue\ \ \ \ \ \ \ \:c\ \ \ \ \ \ \ continue\ evaluation=
+
+#: reploop.lisp:317
+!\nContinue\ \ \ \ \ \ \ \:c\ \ \ \ \ \ \ continue\ evaluation\nStep\ \ \ \ \ \ \ \ \ \ \ \:s\ \ \ \ \ \ \ step\ into\ form\:\ evaluate\ this\ form\ in\ single\ step\ mode\nNext\ \ \ \ \ \ \ \ \ \ \ \:n\ \ \ \ \ \ \ step\ over\ form\:\ evaluate\ this\ form\ at\ once\nOver\ \ \ \ \ \ \ \ \ \ \ \:o\ \ \ \ \ \ \ step\ over\ this\ level\:\ evaluate\ at\ once\ up\ to\ the\ next\ return\nContinue\ \ \ \ \ \ \ \:c\ \ \ \ \ \ switch\ off\ single\ step\ mode,\ continue\ evaluation\n--\ Step-until\ \:su,\ Next-until\ \:nu,\ Over-until\ \:ou,\ Continue-until\ \:cu\ --\n\ \ \ \ \ \ \ \ \ \ \ same\ as\ above,\ specify\ a\ condition\ when\ to\ stop=
+
+#: reploop.lisp:398
+!Unprintable\ error\ message.=
+
+#: reploop.lisp:409
+!You\ can\ continue\ (by\ typing\ 'continue').=
+
+#: reploop.lisp:425
+!The\ following\ restarts\ are\ available,\ too\:=
+
+#: reploop.lisp:426
+!The\ following\ restarts\ are\ available\:=
+
+#: reploop.lisp:523 reploop.lisp:562
+!step\ =
+
+#: reploop.lisp:527
+!no\ values=
+
+#: reploop.lisp:528
+!value\:\ =
+
+#: reploop.lisp:531
+!\ values\:\ =
+
+#: reploop.lisp:597
+!condition\ when\ to\ stop\:\ =
+
+#: dribble.lisp:19
+!Already\ dribbling\ to\ ~S=
+
+#: dribble.lisp:105
+!Currently\ not\ dribbling.=
+
+#: describe.lisp:44
+!constant=
+
+#: describe.lisp:46
+!symbol-macro=
+
+#: describe.lisp:47
+!variable=
+
+#: describe.lisp:54
+!type=
+
+#: describe.lisp:60
+!class=
+
+#: describe.lisp:146
+!~%Slots\:=
+
+#: describe.lisp:153
+!unbound=
+
+#: describe.lisp:156
+!~%No\ slots.=
+
+#: describe.lisp:163
+!a\ foreign\ pointer=
+
+#: describe.lisp:166
+!a\ foreign\ address=
+
+#: describe.lisp:169
+!a\ foreign\ variable\ of\ foreign\ type\ ~S.=
+
+#: describe.lisp:173
+!a\ foreign\ function\ taking\ foreign\ types\ ~\:S\ and\ returning\ foreign\ type\ ~S.=
+
+#: describe.lisp:177
+!a\ byte\ specifier,\ denoting\ the\ ~S\ bits\ starting\ at\ bit\ position\ ~S\ of\ an\ integer.=
+
+#: describe.lisp:180
+!a\ special\ form\ handler.=
+
+#: describe.lisp:182
+!a\ load-time\ evaluation\ promise.=
+
+#: describe.lisp:184
+!a\ symbol\ macro\ handler.=
+
+#: describe.lisp:186
+!a\ macro\ expander.=
+
+#: describe.lisp:188
+!a\ function\ with\ alternative\ macro\ expander.=
+
+#: describe.lisp:190
+!an\ encoding.=
+
+#: describe.lisp:195
+!a\ GC-invisible\ pointer\ to\ ~S.=
+
+#: describe.lisp:198
+!a\ GC-invisible\ pointer\ to\ a\ now\ defunct\ object.=
+
+#: describe.lisp:200
+!a\ label\ used\ for\ resolving\ \#~D\#\ references\ during\ READ.=
+
+#: describe.lisp:204
+!a\ pointer\ into\ the\ stack.\ It\ points\ to\:=
+
+#: describe.lisp:207
+!a\ special-purpose\ object.=
+
+#: describe.lisp:209
+!a\ machine\ address.=
+
+#: describe.lisp:211
+!an\ instance\ of\ the\ CLOS\ class\ ~S.=
+
+#: describe.lisp:215
+!a\ structure\ of\ type\ ~S.=
+
+#: describe.lisp:219
+!~%As\ such,\ it\ is\ also\ a\ structure\ of\ type\ ~{~S~^,\ ~}.=
+
+#: describe.lisp:227
+!a\ dotted\ list\ of\ length\ ~S.=
+
+#: describe.lisp:229
+!a\ cons.=
+
+#: describe.lisp:232
+!a\ list\ of\ length\ ~S.=
+
+#: describe.lisp:234
+!a\ cyclic\ list.=
+
+#: describe.lisp:236
+!the\ empty\ list,\ =
+
+#: describe.lisp:239
+!the\ symbol\ ~S,\ =
+
+#: describe.lisp:243
+!lies\ in\ ~S=
+
+#: describe.lisp:246
+!is\ uninterned=
+
+#: describe.lisp:260
+!,\ is\ accessible\ in\ the\ package~\:[~;s~]\ ~{~A~^,\ ~}=
+
+#: describe.lisp:265
+!,\ is\ a\ keyword=
+
+#: describe.lisp:268
+!,\ a\ constant=
+
+#: describe.lisp:270
+!,\ a\ variable\ declared\ SPECIAL=
+
+#: describe.lisp:271
+!,\ a\ variable=
+
+#: describe.lisp:273
+!\ (macro\:\ ~s)=
+
+#: describe.lisp:276
+!,\ value\:\ ~s=
+
+#: describe.lisp:279
+!,\ names\ =
+
+#: describe.lisp:281
+!a\ special\ operator=
+
+#: describe.lisp:283
+!\ with\ macro\ definition=
+
+#: describe.lisp:285
+!a~\:[~;\ deprecated~]\ function=
+
+#: describe.lisp:288
+!a\ macro=
+
+#: describe.lisp:293
+!,\ names\ a\ type=
+
+#: describe.lisp:297
+!,\ names\ a\ class=
+
+#: describe.lisp:303
+!,\ has\ the\ propert~@P\ ~{~S~^,\ ~}=
+
+#: describe.lisp:306 describe.lisp:340 describe.lisp:363 describe.lisp:382
+#: describe.lisp:425
+!.=
+
+#: describe.lisp:310
+!~%Documentation\ as\ a\ ~a\:~%~a=
+
+#: describe.lisp:312 describe.lisp:451
+!~%For\ more\ information,\ evaluate\ ~{~S~^\ or\ ~}.=
+
+#: describe.lisp:316
+!an\ integer,\ uses\ ~S\ bit~\:p,\ is\ represented\ as\ a\ ~(~A~).=
+
+#: describe.lisp:319
+!a\ rational,\ not\ integral\ number.=
+
+#: describe.lisp:321
+!a\ float\ with\ ~S\ bits\ of\ mantissa\ (~(~A~)).=
+
+#: describe.lisp:324
+!a\ complex\ number\ =
+
+#: describe.lisp:329
+!at\ the\ origin=
+
+#: describe.lisp:330
+!on\ the\ ~\:[posi~;nega~]tive\ real\ axis=
+
+#: describe.lisp:333
+!on\ the\ ~\:[posi~;nega~]tive\ imaginary\ axis=
+
+#: describe.lisp:335
+!in\ the\ ~\:[~\:[first~;fourth~]~;~\:[second~;third~]~]\ quadrant=
+
+#: describe.lisp:337
+!\ of\ the\ Gaussian\ number\ plane.=
+
+#: describe.lisp:339
+!a\ character=
+
+#: describe.lisp:344
+!~%Unicode\ name\:\ ~A=
+
+#: describe.lisp:345
+!~%It\ is\ not\ defined\ by\ the\ Unicode\ standard.=
+
+#: describe.lisp:346
+!~%It\ is\ a\ ~\:[non-~;~]printable\ character.=
+
+#: describe.lisp:349
+!~%Its\ use\ is\ non-portable.=
+
+#: describe.lisp:351
+!a~\:[~\:[\ closed\ ~;n\ output-~]~;~\:[n\ input-~;n\ input/output-~]~]stream.=
+
+#: describe.lisp:357
+!the\ package\ named\ ~A=
+
+#: describe.lisp:361
+!.\ It\ has\ the\ nicknames\ ~{~A~^,\ ~}=
+
+#: describe.lisp:366
+!~%It\ =
+
+#: describe.lisp:368
+!imports\ the\ external\ symbols\ of\ the\ package~\:[~;s~]\ ~{~A~^,\ ~}\ and\ =
+
+#: describe.lisp:373
+!exports\ ~\:[no\ symbols~;the\ symbols~\:*~{~<~%~\:;\ ~S~>~^~}~%~]=
+
+#: describe.lisp:375
+!exports\ ~[no\ symbols~\:;~\:*~\:d\ symbols~]=
+
+#: describe.lisp:378
+!\ to\ the\ package~\:[~;s~]\ ~{~A~^,\ ~}=
+
+#: describe.lisp:381
+!,\ but\ no\ package\ uses\ these\ exports=
+
+#: describe.lisp:383
+!a\ deleted\ package.=
+
+#: describe.lisp:385
+!a\ hash\ table\ with\ ~S\ entr~\:@P.=
+
+#: describe.lisp:388
+!~\:[a~;the\ Common\ Lisp~]\ readtable.=
+
+#: describe.lisp:391
+!a\ ~\:[~;portable\ ~]pathname~\:[.~;~\:*,\ with\ the\ following\ components\:~{~A~}~]=
+
+#: describe.lisp:406
+!a\ random-state.=
+
+#: describe.lisp:410
+!a~\:[~;\ simple~]\ ~A\ dimensional\ array=
+
+#: describe.lisp:413
+!\ (vector)=
+
+#: describe.lisp:415
+!\ of\ ~(~A~)s=
+
+#: describe.lisp:418
+!,\ adjustable=
+
+#: describe.lisp:420
+!,\ of\ size\ ~{~S~^\ x\ ~}=
+
+#: describe.lisp:423
+!\ and\ current\ length\ (fill-pointer)\ ~S=
+
+#: describe.lisp:430
+!a\ foreign\ function.=
+
+#: describe.lisp:436
+!a\ built-in\ system\ function.=
+
+#: describe.lisp:444
+!a~\:[n\ interpret~;\ compil~]ed\ function.=
+
+#: describe.lisp:460
+!~%argument\ list\:\ ~\:S=
+
+#: describe.lisp:463
+!~%documentation\:\ ~A=
+
+#: describe.lisp:468
+!~&~%~A\ [see\ above]=
+
+#: describe.lisp:471
+!~&~%~A\ is\ =
+
+#: describe.lisp:535
+!~S\:\ ~S\ is\ not\ a\ function.=
+
+#: describe.lisp:564
+!~%Argument\ list\:\ =
+
+#: room.lisp:17
+!~S\:\ argument\ must\ be\ ~S,\ ~S\ or\ ~S,\ not\ ~S=
+
+#: room.lisp:51 room.lisp:215
+!Total=
+
+#: room.lisp:59
+!~%Bytes\ permanently\ allocated\:\ \ \ ~9D~%Bytes\ currently\ in\ use\:\ \ \ \ \ \ \ \ ~9D~%Bytes\ available\ until\ next\ GC\:\ ~9D~%=
+
+#: edit.lisp:30
+!No\ external\ editor\ installed.=
+
+#: edit.lisp:102
+!~S\ cannot\ be\ edited.=
+
+#: edit.lisp:121
+!~S\:\ source\ code\ for\ ~S\ not\ available.=
+
+#: macros3.lisp:13
+!The\ form\ ~S\ yielded\ ~\:[no\ values~;~\:*~{~S~^\ ;\ ~}~]\ ,~@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ that's\ not\ of\ type\ ~S.=
+
+#: macros3.lisp:64
+!LETF*\ code\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: macros3.lisp:83
+!illegal\ syntax\ in\ LETF*\ binding\:\ ~S=
+
+#: macros3.lisp:227
+!LETF\ code\ contains\ a\ dotted\ list,\ ending\ with\ ~S=
+
+#: macros3.lisp:246
+!illegal\ syntax\ in\ LETF\ binding\:\ ~S=
+
+#: foreign1.lisp:86
+!Cannot\ map\ string\ ~S\ to\ C\ since\ it\ contains\ a\ character\ ~S=
+
+#: foreign1.lisp:128
+!Incomplete\ FFI\ type\ ~S\ is\ not\ allowed\ here.=
+
+#: foreign1.lisp:134
+!FFI\ type\ should\ be\ a\ symbol,\ not\ ~S=
+
+#: foreign1.lisp:138
+!Invalid\ FFI\ type\:\ ~S=
+
+#: foreign1.lisp:155 foreign1.lisp:220
+!Invalid\ ~S\ component\:\ ~S=
+
+#: foreign1.lisp:329
+!Invalid\ option\ in\ ~S\:\ ~S=
+
+#: foreign1.lisp:333
+!Only\ one\ ~S\ option\ is\ allowed\:\ ~S=
+
+#: foreign1.lisp:350
+!Invalid\ parameter\ specification\ in\ ~S\:\ ~S=
+
+#: foreign1.lisp:411
+!The\ name\ must\ be\ a\ string,\ not\ ~S=
+
+#: foreign1.lisp:416
+!The\ name\ ~S\ is\ not\ a\ valid\ C\ identifier=
+
+#: foreign1.lisp:671
+!illegal\ foreign\ data\ type\ ~S=
+
+#: foreign1.lisp:801
+!~S\:\ ~S\ option\ missing\ in\ ~S=
+
+#: foreign1.lisp:996
+!~S\:\ \:OUT\ argument\ is\ not\ a\ pointer\:\ ~S=
+
+#: foreign1.lisp:1060
+!~S\ is\ only\ allowed\ after\ ~S\:\ ~S=
+
+#: affi1.lisp:41
+!Basename\ ~S\ not\ a\ keyword\ or\ libraryname\ ~S\ not\ a\ string=
+
+#: affi1.lisp:48
+!Library\ redefinition\:\ old\ ~S,\ new\ ~S=
+
+#: affi1.lisp:58
+!Unknown\ library\:\ ~S=
+
+#: affi1.lisp:85
+!Library\ ~S\ is\ not\ open=
+
+#: affi1.lisp:147
+!Unknown\ function\ of\ library\ ~S\:\ ~S=
+
+#: affi1.lisp:173
+!Offset\ must\ be\ a\ fixnum\:\ ~S=
+
+#: affi1.lisp:184
+!~&;;\ redefining\ foreign\ library\ function\ ~S~%;;\ \ from\ ~S\ to\ ~S~%=
+
+#: affi1.lisp:203
+!Unknown\ register\:\ ~S=
+
+#: affi1.lisp:215
+!Invalid\ parameter\ specification\ ~S\ in\ function\ ~S=
+
+#: affi1.lisp:227
+!Unknown\ library\ function\:\ ~S=
+
+#: affi1.lisp:244
+!Bad\ number\ of\ arguments\ for\ ~S\:\ ~S=
+
+#: rexx1.lisp:146
+!No\ waiting\ for\ ~S\ possible.=
+
+#: defs3.lisp:231
+!~S\:\ argument\ ~S\ should\ be\ a\ string\ or\ a\ symbol=
diff --git a/gettext-tools/tests/xgettext-24 b/gettext-tools/tests/xgettext-24
new file mode 100755 (executable)
index 0000000..eb82a66
--- /dev/null
@@ -0,0 +1,82 @@
+#! /bin/sh
+
+# Test C, C++, JavaProperties extractors.
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles xg-test24.in.properties xg-test24.c xg-test24.cc"
+cat <<EOF > xg-test24.in.properties
+#: file1.c:199
+#, fuzzy
+!extract\ me=some text to get fuzzy copied to result
+
+#: file2.cc:200
+!what\ about\ me=
+
+#: file3.c:10
+#, c-format, fuzzy
+!hello=Again some text for fuzzy
+EOF
+
+cat <<EOF > xg-test24.c
+#include <libintl.h>
+#include <stdio.h>
+int
+main (int argc, char *argv[])
+{
+  printf (dcgettext ("hello", "Hello, world."));
+  return 0;
+}
+EOF
+
+cat <<EOF > xg-test24.cc
+#include <iostream.h>
+#include <libintl.h>
+#include <locale.h>
+int
+main (int argc, char *argv[])
+{
+  cout << dcgettext ("hello", "Hello world!", LC_MESSAGES) << endl;
+  return 0;
+}
+EOF
+
+tmpfiles="$tmpfiles xg-test24.po"
+: ${XGETTEXT=xgettext}
+${XGETTEXT} --omit-header -n xg-test24.in.properties \
+  xg-test24.c xg-test24.cc -d xg-test24
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles xg-test24.ok"
+cat <<EOF > xg-test24.ok
+#: file1.c:199
+#, fuzzy
+msgid "extract me"
+msgstr "some text to get fuzzy copied to result"
+
+#: file2.cc:200
+msgid "what about me"
+msgstr ""
+
+#: file3.c:10
+#, fuzzy, c-format
+msgid "hello"
+msgstr "Again some text for fuzzy"
+
+#: xg-test24.c:6
+msgid "Hello, world."
+msgstr ""
+
+#: xg-test24.cc:7
+msgid "Hello world!"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-test24.ok xg-test24.po
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result