summaryrefslogtreecommitdiffstats
path: root/gettext-tools/src/xgettext.c
diff options
context:
space:
mode:
Diffstat (limited to 'gettext-tools/src/xgettext.c')
-rw-r--r--gettext-tools/src/xgettext.c82
1 files changed, 78 insertions, 4 deletions
diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c
index f9156eb..310b349 100644
--- a/gettext-tools/src/xgettext.c
+++ b/gettext-tools/src/xgettext.c
@@ -58,6 +58,8 @@
#include "po-charset.h"
#include "msgl-iconv.h"
#include "msgl-ascii.h"
+#include "msgl-check.h"
+#include "po-xerror.h"
#include "po-time.h"
#include "write-catalog.h"
#include "write-po.h"
@@ -66,6 +68,7 @@
#include "color.h"
#include "format.h"
#include "propername.h"
+#include "sentence.h"
#include "unistr.h"
#include "gettext.h"
@@ -179,6 +182,9 @@ static bool recognize_format_kde;
/* If true, recognize Boost format strings. */
static bool recognize_format_boost;
+/* Syntax checks enabled by default. */
+static enum is_syntax_check default_syntax_check[NSYNTAXCHECKS];
+
/* Canonicalized encoding name for all input files. */
const char *xgettext_global_source_encoding;
@@ -204,6 +210,7 @@ static const struct option long_options[] =
{ "add-location", optional_argument, NULL, 'n' },
{ "boost", no_argument, NULL, CHAR_MAX + 11 },
{ "c++", no_argument, NULL, 'C' },
+ { "check", required_argument, NULL, CHAR_MAX + 17 },
{ "color", optional_argument, NULL, CHAR_MAX + 14 },
{ "copyright-holder", required_argument, NULL, CHAR_MAX + 1 },
{ "debug", no_argument, &do_debug, 1 },
@@ -236,6 +243,7 @@ static const struct option long_options[] =
{ "package-version", required_argument, NULL, CHAR_MAX + 13 },
{ "properties-output", no_argument, NULL, CHAR_MAX + 6 },
{ "qt", no_argument, NULL, CHAR_MAX + 9 },
+ { "sentence-end", required_argument, NULL, CHAR_MAX + 18 },
{ "sort-by-file", no_argument, NULL, 'F' },
{ "sort-output", no_argument, NULL, 's' },
{ "strict", no_argument, NULL, 'S' },
@@ -346,7 +354,7 @@ main (int argc, char *argv[])
init_flag_table_vala ();
while ((optchar = getopt_long (argc, argv,
- "ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTVw:x:",
+ "ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTVw:W:x:",
long_options, NULL)) != EOF)
switch (optchar)
{
@@ -602,6 +610,26 @@ main (int argc, char *argv[])
message_print_style_filepos (filepos_comment_none);
break;
+ case CHAR_MAX + 17: /* --check */
+ if (strcmp (optarg, "ellipsis-unicode") == 0)
+ default_syntax_check[sc_ellipsis_unicode] = yes;
+ else if (strcmp (optarg, "space-ellipsis") == 0)
+ default_syntax_check[sc_space_ellipsis] = yes;
+ else if (strcmp (optarg, "quote-unicode") == 0)
+ default_syntax_check[sc_quote_unicode] = yes;
+ else
+ error (EXIT_FAILURE, 0, _("syntax check '%s' unknown"), optarg);
+ break;
+
+ case CHAR_MAX + 18: /* --sentence-end */
+ if (strcmp (optarg, "single-space") == 0)
+ sentence_end_required_spaces = 1;
+ else if (strcmp (optarg, "double-space") == 0)
+ sentence_end_required_spaces = 2;
+ else
+ error (EXIT_FAILURE, 0, _("sentence end type '%s' unknown"), optarg);
+ break;
+
default:
usage (EXIT_FAILURE);
/* NOTREACHED */
@@ -836,6 +864,24 @@ warning: file '%s' extension '%s' is unknown; will try C"), filename, extension)
else if (sort_by_msgid)
msgdomain_list_sort_by_msgid (mdlp);
+ /* Check syntax of messages. */
+ {
+ int nerrors = 0;
+
+ for (i = 0; i < mdlp->nitems; i++)
+ {
+ message_list_ty *mlp = mdlp->item[i]->messages;
+ nerrors = syntax_check_message_list (mlp);
+ }
+
+ /* Exit with status 1 on any error. */
+ if (nerrors > 0)
+ error (EXIT_FAILURE, 0,
+ ngettext ("found %d fatal error", "found %d fatal errors",
+ nerrors),
+ nerrors);
+ }
+
/* Write the PO file. */
msgdomain_list_print (mdlp, file_name, output_syntax, force_po, do_debug);
@@ -921,6 +967,14 @@ Operation mode:\n"));
preceding keyword lines in output file\n\
-c, --add-comments place all comment blocks preceding keyword lines\n\
in output file\n"));
+ printf (_("\
+ --check=NAME perform syntax check on messages\n\
+ (ellipsis-unicode, space-ellipsis,\n\
+ quote-unicode)\n"));
+ printf (_("\
+ --sentence-end=TYPE type describing the end of sentence\n\
+ (single-space, which is the default, \n\
+ or double-space)\n"));
printf ("\n");
printf (_("\
Language specific options:\n"));
@@ -1644,8 +1698,8 @@ xgettext_record_flag (const char *optionstring)
flag += 5;
}
- /* Unlike po_parse_comment_special(), we don't accept "fuzzy" or "wrap"
- here - it has no sense. */
+ /* Unlike po_parse_comment_special(), we don't accept "fuzzy",
+ "wrap", or "check" here - it has no sense. */
if (strlen (flag) >= 7
&& memcmp (flag + strlen (flag) - 7, "-format", 7) == 0)
{
@@ -2238,6 +2292,7 @@ remember_a_message (message_list_ty *mlp, char *msgctxt, char *msgid,
enum is_format is_format[NFORMATS];
struct argument_range range;
enum is_wrap do_wrap;
+ enum is_syntax_check do_syntax_check[NSYNTAXCHECKS];
message_ty *mp;
char *msgstr;
size_t i;
@@ -2264,6 +2319,8 @@ remember_a_message (message_list_ty *mlp, char *msgctxt, char *msgid,
range.min = -1;
range.max = -1;
do_wrap = undecided;
+ for (i = 0; i < NSYNTAXCHECKS; i++)
+ do_syntax_check[i] = undecided;
if (msgctxt != NULL)
CONVERT_STRING (msgctxt, lc_string);
@@ -2297,6 +2354,8 @@ meta information, not the empty string.\n")));
for (i = 0; i < NFORMATS; i++)
is_format[i] = mp->is_format[i];
do_wrap = mp->do_wrap;
+ for (i = 0; i < NSYNTAXCHECKS; i++)
+ do_syntax_check[i] = mp->do_syntax_check[i];
}
else
{
@@ -2376,12 +2435,13 @@ meta information, not the empty string.\n")));
enum is_format tmp_format[NFORMATS];
struct argument_range tmp_range;
enum is_wrap tmp_wrap;
+ enum is_syntax_check tmp_syntax_check[NSYNTAXCHECKS];
bool interesting;
t += strlen ("xgettext:");
po_parse_comment_special (t, &tmp_fuzzy, tmp_format, &tmp_range,
- &tmp_wrap);
+ &tmp_wrap, tmp_syntax_check);
interesting = false;
for (i = 0; i < NFORMATS; i++)
@@ -2400,6 +2460,12 @@ meta information, not the empty string.\n")));
do_wrap = tmp_wrap;
interesting = true;
}
+ for (i = 0; i < NSYNTAXCHECKS; i++)
+ if (tmp_syntax_check[i] != undecided)
+ {
+ do_syntax_check[i] = tmp_syntax_check[i];
+ interesting = true;
+ }
/* If the "xgettext:" marker was followed by an interesting
keyword, and we updated our is_format/do_wrap variables,
@@ -2525,6 +2591,14 @@ meta information, not the empty string.\n")));
mp->do_wrap = do_wrap == no ? no : yes; /* By default we wrap. */
+ for (i = 0; i < NSYNTAXCHECKS; i++)
+ {
+ if (do_syntax_check[i] == undecided)
+ do_syntax_check[i] = default_syntax_check[i] == yes ? yes : no;
+
+ mp->do_syntax_check[i] = do_syntax_check[i];
+ }
+
/* Warn about the use of non-reorderable format strings when the programming
language also provides reorderable format strings. */
warn_format_string (is_format, mp->msgid, pos, "msgid");