]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Add new check bullet-unicode
authorDaiki Ueno <ueno@gnu.org>
Mon, 22 Feb 2016 07:43:16 +0000 (16:43 +0900)
committerDaiki Ueno <ueno@gnu.org>
Mon, 22 Feb 2016 08:59:40 +0000 (17:59 +0900)
* gettext-tools/src/xgettext.c (main): Generalize --check option
handling.
* gettext-tools/src/message.h (enum syntax_check_type): New enum value
sc_bullet_unicode.
(NSYNTAXCHECKS): Increment.
* gettext-tools/src/message.c (syntax_check_name): Add name for
sc_bullet_unicode.
* gettext-tools/src/msgl-check.c (struct bullet_ty, struct
bullet_stack_ty): New struct.
(bullet_stack): New variable.
(syntax_check_bullet_unicode): New function.
(sc_funcs): Register syntax_check_bullet_unicode as a check function for
sc_bullet_unicode.
* gettext-tools/tests/xgettext-14: Add tests for --check=bullet-unicode

gettext-tools/doc/xgettext.texi
gettext-tools/src/message.c
gettext-tools/src/message.h
gettext-tools/src/msgl-check.c
gettext-tools/src/xgettext.c
gettext-tools/tests/xgettext-14

index d6a5f019f2bfc1e193fb5db7d8a6601f86c4ca34..e2700d9f5b195a9891ebb1ec21be38a9a25262f9 100644 (file)
@@ -160,6 +160,9 @@ Prohibit whitespace before an ellipsis character
 @item quote-unicode
 Prefer Unicode quotation marks over ASCII @code{"'`}
 
+@item bullet-unicode
+Prefer Unicode bullet character over ASCII @code{*} or @code{-}
+
 @end table
 
 The option has an effect on all input files.  To enable or disable
index 9d645424cb7820219db5a17899897a3f799ec3b3..a5ecdccb4753540129962c48f94b50d420cfbc0b 100644 (file)
@@ -110,7 +110,8 @@ const char *const syntax_check_name[NSYNTAXCHECKS] =
 {
   /* sc_ellipsis_unicode */     "ellipsis-unicode",
   /* sc_space_ellipsis */       "space-ellipsis",
-  /* sc_quote_unicode */        "quote-unicode"
+  /* sc_quote_unicode */        "quote-unicode",
+  /* sc_bullet_unicode */       "bullet-unicode"
 };
 
 
index 6000e41ed576e839846b7c012c2b6baee01e58e1..7b333f2fbc0703c4892adff0518879135d10efdb 100644 (file)
@@ -120,9 +120,10 @@ enum syntax_check_type
 {
   sc_ellipsis_unicode,
   sc_space_ellipsis,
-  sc_quote_unicode
+  sc_quote_unicode,
+  sc_bullet_unicode
 };
-#define NSYNTAXCHECKS 3
+#define NSYNTAXCHECKS 4
 extern DLL_VARIABLE const char *const syntax_check_name[NSYNTAXCHECKS];
 
 /* Is current msgid subject to a syntax check?  */
index 7eb2f5e18edfd5c687e42ff357a0bf07c79d4f9c..5bbca85a8d57963b63556ae5b6f6f5d9e9d79f0b 100644 (file)
@@ -1068,13 +1068,116 @@ syntax_check_quote_unicode (const message_ty *mp, const char *msgid)
   return arg.seen_errors;
 }
 
+struct bullet_ty
+{
+  int c;
+  size_t depth;
+};
+
+struct bullet_stack_ty
+{
+  struct bullet_ty *items;
+  size_t nitems;
+  size_t nitems_max;
+};
+
+static struct bullet_stack_ty bullet_stack;
+
+static int
+syntax_check_bullet_unicode (const message_ty *mp, const char *msgid)
+{
+  const char *str = msgid;
+  const char *str_limit = str + strlen (msgid);
+  struct bullet_ty *last_bullet = NULL;
+  bool seen_error = false;
+
+  bullet_stack.nitems = 0;
+
+  while (str < str_limit)
+    {
+      const char *p = str, *end;
+
+      while (p < str_limit && c_isspace (*p))
+        p++;
+
+      if ((*p == '*' || *p == '-') && *(p + 1) == ' ')
+        {
+          size_t depth = p - str;
+          if (last_bullet == NULL || depth > last_bullet->depth)
+            {
+              struct bullet_ty bullet;
+
+              bullet.c = *p;
+              bullet.depth = depth;
+
+              if (bullet_stack.nitems >= bullet_stack.nitems_max)
+                {
+                  bullet_stack.nitems_max = 2 * bullet_stack.nitems_max + 4;
+                  bullet_stack.items = xrealloc (bullet_stack.items,
+                                                 bullet_stack.nitems_max
+                                                 * sizeof (struct bullet_ty));
+                }
+
+              last_bullet = &bullet_stack.items[bullet_stack.nitems++];
+              memcpy (last_bullet, &bullet, sizeof (struct bullet_ty));
+            }
+          else
+            {
+              if (depth < last_bullet->depth)
+                {
+                  if (bullet_stack.nitems > 1)
+                    {
+                      bullet_stack.nitems--;
+                      last_bullet =
+                        &bullet_stack.items[bullet_stack.nitems - 1];
+                    }
+                  else
+                    last_bullet = NULL;
+                }
+
+              if (last_bullet && depth == last_bullet->depth)
+                {
+                  if (last_bullet->c != *p)
+                    last_bullet->c = *p;
+                  else
+                    {
+                      seen_error = true;
+                      break;
+                    }
+                }
+            }
+        }
+      else
+        {
+          bullet_stack.nitems = 0;
+          last_bullet = NULL;
+        }
+
+      end = strchrnul (str, '\n');
+      str = end + 1;
+    }
+
+  if (seen_error)
+    {
+      char *msg;
+      msg = xasprintf (_("ASCII bullet ('%c') instead of Unicode"),
+                       last_bullet->c);
+      po_xerror (PO_SEVERITY_ERROR, mp, NULL, 0, 0, false, msg);
+      free (msg);
+      return 1;
+    }
+
+  return 0;
+}
+
 
 typedef int (* syntax_check_function) (const message_ty *mp, const char *msgid);
 static const syntax_check_function sc_funcs[NSYNTAXCHECKS] =
 {
   syntax_check_ellipsis_unicode,
   syntax_check_space_ellipsis,
-  syntax_check_quote_unicode
+  syntax_check_quote_unicode,
+  syntax_check_bullet_unicode
 };
 
 /* Perform all syntax checks on a non-obsolete message.
index 77f9d123913812ec0a0d8d1a5be3899f65b5b179..f269ce711eba2a0bd675d263d338d3936602c3df 100644 (file)
@@ -637,13 +637,15 @@ main (int argc, char *argv[])
         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
+        for (i = 0; i < NSYNTAXCHECKS; i++)
+          {
+            if (strcmp (optarg, syntax_check_name[i]) == 0)
+              {
+                default_syntax_check[i] = yes;
+                break;
+              }
+          }
+        if (i == NSYNTAXCHECKS)
           error (EXIT_FAILURE, 0, _("syntax check '%s' unknown"), optarg);
         break;
 
index b769b2fc0193b31af27bbb9b2900ee4a4599ad4f..8df8a041063b18dff8fd62bf333cbeda1cc8e2dd 100755 (executable)
@@ -96,3 +96,40 @@ LANGUAGE= LC_ALL=C ${XGETTEXT} --omit-header --add-comments --check=quote-unicod
 
 test `grep -c 'ASCII double quote' xg-quote-u.err` = 4 || exit 1
 test `grep -c 'ASCII single quote' xg-quote-u.err` = 12 || exit 1
+
+# --check=bullet-unicode
+cat <<\EOF > xg-bullet-u1.c
+gettext ("The following is a list of items:\n\
+* item 1\n\
+* item 2\n\
+* item 3\n");
+EOF
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --omit-header --add-comments --check=bullet-unicode -d xg-bullet-u1.tmp xg-bullet-u1.c 2>xg-bullet-u1.err
+
+test `grep -c 'ASCII bullet' xg-bullet-u1.err` = 1 || { cat xg-bullet-u1.err; exit 1; }
+
+cat <<\EOF > xg-bullet-u2.c
+gettext ("The following is a list of items:\n\
+* item 1\n\
+ - item 2\n\
+* item 3\n");
+EOF
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --omit-header --add-comments --check=bullet-unicode -d xg-bullet-u2.tmp xg-bullet-u2.c 2>xg-bullet-u2.err
+
+test `grep -c 'ASCII bullet' xg-bullet-u2.err` = 1 || { cat xg-bullet-u2.err; exit 1; }
+
+cat <<\EOF > xg-bullet-u3.c
+gettext ("The following is NOT a list of items:\n\
+* item 1\n\
+- item 2\n\
+* item 3\n");
+EOF
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --omit-header --add-comments --check=bullet-unicode -d xg-bullet-u3.tmp xg-bullet-u3.c 2>xg-bullet-u3.err
+
+test `grep -c 'ASCII bullet' xg-bullet-u3.err` = 0 || { cat xg-bullet-u3.err; exit 1; }