summaryrefslogtreecommitdiffstats
path: root/gettext-tools
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2015-10-02 12:38:14 +0900
committerDaiki Ueno <ueno@gnu.org>2015-12-04 13:02:40 +0900
commit0daa0c191f18a1cdfd0cf7afa87d0891d11b1228 (patch)
treec1c1c891bd433ddc5fb9fb1af042c4c4e1eb41c1 /gettext-tools
parent95d20e87121549fc014e25dbcd1e417f31f5344e (diff)
downloadexternal_gettext-0daa0c191f18a1cdfd0cf7afa87d0891d11b1228.zip
external_gettext-0daa0c191f18a1cdfd0cf7afa87d0891d11b1228.tar.gz
external_gettext-0daa0c191f18a1cdfd0cf7afa87d0891d11b1228.tar.bz2
xgettext: Rewrite GSettings scanner in ITS
* gettext-tools/its/gsettings.its: New file. * gettext-tools/its/gsettings.loc: New file. * gettext-tools/its/Makefile.am (dist_its_DATA): Add new files. * gettext-tools/src/Makefile.am (xgettext_SOURCES): Remove x-gsettings.c. * gettext-tools/src/x-gsettings.c: Remove. * gettext-tools/src/x-gsettings.h (EXTENSIONS_GSETTINGS): Set language field to NULL. (SCANNER_GSETTINGS): Set func field to NULL.
Diffstat (limited to 'gettext-tools')
-rw-r--r--gettext-tools/its/Makefile.am2
-rw-r--r--gettext-tools/its/gsettings.its14
-rw-r--r--gettext-tools/its/gsettings.loc6
-rw-r--r--gettext-tools/src/Makefile.am2
-rw-r--r--gettext-tools/src/x-gsettings.c387
-rw-r--r--gettext-tools/src/x-gsettings.h14
6 files changed, 27 insertions, 398 deletions
diff --git a/gettext-tools/its/Makefile.am b/gettext-tools/its/Makefile.am
index 3028945..6485628 100644
--- a/gettext-tools/its/Makefile.am
+++ b/gettext-tools/its/Makefile.am
@@ -20,4 +20,4 @@ AUTOMAKE_OPTIONS = 1.2 gnits
pkgdatadir = $(datadir)/gettext
itsdir = $(pkgdatadir)$(PACKAGE_SUFFIX)/its
-dist_its_DATA = appdata.loc appdata.its
+dist_its_DATA = gsettings.loc gsettings.its appdata.loc appdata.its
diff --git a/gettext-tools/its/gsettings.its b/gettext-tools/its/gsettings.its
new file mode 100644
index 0000000..85c6358
--- /dev/null
+++ b/gettext-tools/its/gsettings.its
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<its:rules xmlns:its="http://www.w3.org/2005/11/its"
+ xmlns:gt="https://www.gnu.org/s/gettext/ns/its/extensions/1.0"
+ version="2.0">
+ <its:translateRule selector="/schemalist" translate="no"/>
+
+ <its:translateRule selector="//summary | //description" translate="yes"/>
+
+ <its:translateRule selector="//default[@l10n]" translate="yes"/>
+ <gt:contextRule selector="//default[@context]" contextPointer="@context"/>
+
+ <gt:preserveSpaceRule selector="//default" space="trim"/>
+ <gt:escapeRule selector="/schemalist" encode="no"/>
+</its:rules>
diff --git a/gettext-tools/its/gsettings.loc b/gettext-tools/its/gsettings.loc
new file mode 100644
index 0000000..e5967f1
--- /dev/null
+++ b/gettext-tools/its/gsettings.loc
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<locatingRules>
+ <locatingRule name="GSettings" pattern="*.gschema.xml">
+ <documentRule localName="schemalist" target="gsettings.its"/>
+ </locatingRule>
+</locatingRules>
diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am
index 52f351f..ff3f1e1 100644
--- a/gettext-tools/src/Makefile.am
+++ b/gettext-tools/src/Makefile.am
@@ -182,7 +182,7 @@ endif
xgettext_SOURCES += \
x-c.c x-po.c x-sh.c x-python.c x-lisp.c x-elisp.c x-librep.c x-scheme.c \
x-smalltalk.c x-java.c x-csharp.c x-awk.c x-ycp.c x-tcl.c x-perl.c x-php.c \
- x-rst.c x-glade.c x-lua.c x-javascript.c x-vala.c x-gsettings.c \
+ x-rst.c x-glade.c x-lua.c x-javascript.c x-vala.c \
x-desktop.c
if !WOE32DLL
msgattrib_SOURCES = msgattrib.c
diff --git a/gettext-tools/src/x-gsettings.c b/gettext-tools/src/x-gsettings.c
deleted file mode 100644
index 94b339d..0000000
--- a/gettext-tools/src/x-gsettings.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/* xgettext GSettings schema file backend.
- Copyright (C) 2002-2003, 2005-2009, 2013, 2015 Free Software
- Foundation, Inc.
-
- This file was written by Daiki Ueno <ueno@gnu.org>, 2013.
-
- 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-/* Specification. */
-#include "x-gsettings.h"
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "message.h"
-#include "xgettext.h"
-#include "error.h"
-#include "xerror.h"
-#include "xvasprintf.h"
-#include "basename.h"
-#include "progname.h"
-#include "xalloc.h"
-#include "hash.h"
-#include "po-charset.h"
-#include "gettext.h"
-#include "libexpat-compat.h"
-
-#define _(s) gettext(s)
-
-
-/* GSettings schema file is an XML based format.
- The syntax is defined in glib/gio/gschema.dtd and:
- https://developer.gnome.org/gio/unstable/GSettings.html */
-
-
-/* ====================== Keyword set customization. ====================== */
-
-/* If true extract all strings. */
-static bool extract_all = false;
-
-
-/* ============================= XML parsing. ============================= */
-
-#if DYNLOAD_LIBEXPAT || HAVE_LIBEXPAT
-
-/* Accumulator for the extracted messages. */
-static message_list_ty *mlp;
-
-/* Logical filename, used to label the extracted messages. */
-static char *logical_file_name;
-
-/* XML parser. */
-static XML_Parser parser;
-
-enum whitespace_type_ty
-{
- none,
- normalize,
- strip
-};
-typedef enum whitespace_type_ty whitespace_type_ty;
-
-struct element_state
-{
- bool extract_string;
- whitespace_type_ty whitespace;
- char *extracted_context;
- int lineno;
- char *buffer;
- size_t bufmax;
- size_t buflen;
-};
-static struct element_state *stack;
-static size_t stack_size;
-
-static char *
-normalize_whitespace (const char *text, whitespace_type_ty whitespace)
-{
- if (whitespace == none)
- return xstrdup (text);
- else
- {
- char *result, *p;
-
- /* Strip whitespaces at the beginning/end of the text. */
- result = xstrdup (text + strspn (text, " \t\n"));
- for (p = result + strlen (result);
- p > result && (*p == '\0' || *p == ' ' || *p == '\t' || *p == '\n');
- p--)
- ;
- if (p > result)
- *++p = '\0';
-
- /* Normalize whitespaces within the text. */
- if (whitespace == normalize)
- {
- char *end = result + strlen (result);
- for (p = result; *p != '\0';)
- {
- size_t len = strspn (p, " \t\n");
- if (len > 0)
- {
- *p = ' ';
- memmove (p + 1, p + len, end - (p + len));
- end -= len - 1;
- *end = '\0';
- p++;
- }
- p += strcspn (p, " \t\n");
- }
- }
- return result;
- }
-}
-
-/* Ensures stack_size >= size. */
-static void
-ensure_stack_size (size_t size)
-{
- if (size > stack_size)
- {
- stack_size = 2 * stack_size;
- if (stack_size < size)
- stack_size = size;
- stack =
- (struct element_state *)
- xrealloc (stack, stack_size * sizeof (struct element_state));
- }
-}
-
-static size_t stack_depth;
-
-/* Callback called when <element> is seen. */
-static void
-start_element_handler (void *userData, const char *name,
- const char **attributes)
-{
- struct element_state *p;
-
- /* Increase stack depth. */
- stack_depth++;
- ensure_stack_size (stack_depth + 1);
-
- /* Don't extract a string for the containing element. */
- stack[stack_depth - 1].extract_string = false;
-
- p = &stack[stack_depth];
- p->extract_string = extract_all;
- p->extracted_context = NULL;
-
- if (!p->extract_string)
- {
- bool has_translatable = false;
- whitespace_type_ty whitespace = none;
- const char *extracted_context = NULL;
- if (strcmp (name, "summary") == 0 || strcmp (name, "description") == 0)
- {
- has_translatable = true;
- whitespace = normalize;
- }
- else if (strcmp (name, "default") == 0)
- {
- const char *extracted_l10n = NULL;
- const char **attp = attributes;
- while (*attp != NULL)
- {
- if (strcmp (attp[0], "context") == 0)
- extracted_context = attp[1];
- else if (strcmp (attp[0], "l10n") == 0)
- extracted_l10n = attp[1];
- attp += 2;
- }
- if (extracted_l10n != NULL)
- {
- has_translatable = true;
- whitespace = strip;
- }
- }
- p->extract_string = has_translatable;
- p->whitespace = whitespace;
- p->extracted_context =
- (has_translatable && extracted_context != NULL
- ? xstrdup (extracted_context)
- : NULL);
- }
-
- p->lineno = XML_GetCurrentLineNumber (parser);
- p->buffer = NULL;
- p->bufmax = 0;
- p->buflen = 0;
- if (!p->extract_string)
- savable_comment_reset ();
-}
-
-/* Callback called when </element> is seen. */
-static void
-end_element_handler (void *userData, const char *name)
-{
- struct element_state *p = &stack[stack_depth];
-
- /* Actually extract string. */
- if (p->extract_string)
- {
- /* Don't extract the empty string. */
- if (p->buflen > 0)
- {
- lex_pos_ty pos;
-
- if (p->buflen == p->bufmax)
- p->buffer = (char *) xrealloc (p->buffer, p->buflen + 1);
- p->buffer[p->buflen] = '\0';
-
- pos.file_name = logical_file_name;
- pos.line_number = p->lineno;
-
- if (p->buffer != NULL)
- {
- remember_a_message (mlp, p->extracted_context,
- normalize_whitespace (p->buffer,
- p->whitespace),
- null_context, &pos,
- NULL, savable_comment);
- p->extracted_context = NULL;
- }
- }
- }
-
- /* Free memory for this stack level. */
- if (p->extracted_context != NULL)
- free (p->extracted_context);
- if (p->buffer != NULL)
- free (p->buffer);
-
- /* Decrease stack depth. */
- stack_depth--;
-
- savable_comment_reset ();
-}
-
-/* Callback called when some text is seen. */
-static void
-character_data_handler (void *userData, const char *s, int len)
-{
- struct element_state *p = &stack[stack_depth];
-
- /* Accumulate character data. */
- if (len > 0)
- {
- if (p->buflen + len > p->bufmax)
- {
- p->bufmax = 2 * p->bufmax;
- if (p->bufmax < p->buflen + len)
- p->bufmax = p->buflen + len;
- p->buffer = (char *) xrealloc (p->buffer, p->bufmax);
- }
- memcpy (p->buffer + p->buflen, s, len);
- p->buflen += len;
- }
-}
-
-/* Callback called when some comment text is seen. */
-static void
-comment_handler (void *userData, const char *data)
-{
- /* Split multiline comment into lines, and remove leading and trailing
- whitespace. */
- char *copy = xstrdup (data);
- char *p;
- char *q;
-
- for (p = copy; (q = strchr (p, '\n')) != NULL; p = q + 1)
- {
- while (p[0] == ' ' || p[0] == '\t')
- p++;
- while (q > p && (q[-1] == ' ' || q[-1] == '\t'))
- q--;
- *q = '\0';
- savable_comment_add (p);
- }
- q = p + strlen (p);
- while (p[0] == ' ' || p[0] == '\t')
- p++;
- while (q > p && (q[-1] == ' ' || q[-1] == '\t'))
- q--;
- *q = '\0';
- savable_comment_add (p);
- free (copy);
-}
-
-
-static void
-do_extract_gsettings (FILE *fp,
- const char *real_filename, const char *logical_filename,
- msgdomain_list_ty *mdlp)
-{
- mlp = mdlp->item[0]->messages;
-
- /* expat feeds us strings in UTF-8 encoding. */
- xgettext_current_source_encoding = po_charset_utf8;
-
- logical_file_name = xstrdup (logical_filename);
-
- parser = XML_ParserCreate (NULL);
- if (parser == NULL)
- error (EXIT_FAILURE, 0, _("memory exhausted"));
-
- XML_SetElementHandler (parser, start_element_handler, end_element_handler);
- XML_SetCharacterDataHandler (parser, character_data_handler);
- XML_SetCommentHandler (parser, comment_handler);
-
- stack_depth = 0;
-
- while (!feof (fp))
- {
- char buf[4096];
- int count = fread (buf, 1, sizeof buf, fp);
-
- if (count == 0)
- {
- if (ferror (fp))
- error (EXIT_FAILURE, errno, _("\
-error while reading \"%s\""), real_filename);
- /* EOF reached. */
- break;
- }
-
- if (XML_Parse (parser, buf, count, 0) == 0)
- error (EXIT_FAILURE, 0, _("%s:%lu:%lu: %s"), logical_filename,
- (unsigned long) XML_GetCurrentLineNumber (parser),
- (unsigned long) XML_GetCurrentColumnNumber (parser) + 1,
- XML_ErrorString (XML_GetErrorCode (parser)));
- }
-
- if (XML_Parse (parser, NULL, 0, 1) == 0)
- error (EXIT_FAILURE, 0, _("%s:%lu:%lu: %s"), logical_filename,
- (unsigned long) XML_GetCurrentLineNumber (parser),
- (unsigned long) XML_GetCurrentColumnNumber (parser) + 1,
- XML_ErrorString (XML_GetErrorCode (parser)));
-
- XML_ParserFree (parser);
-
- /* Close scanner. */
- logical_file_name = NULL;
- parser = NULL;
-}
-
-#endif
-
-void
-extract_gsettings (FILE *fp,
- const char *real_filename, const char *logical_filename,
- flag_context_list_table_ty *flag_table,
- msgdomain_list_ty *mdlp)
-{
-#if DYNLOAD_LIBEXPAT || HAVE_LIBEXPAT
- if (LIBEXPAT_AVAILABLE ())
- do_extract_gsettings (fp, real_filename, logical_filename, mdlp);
- else
-#endif
- {
- multiline_error (xstrdup (""),
- xasprintf (_("\
-Language \"gsettings\" is not supported. %s relies on expat.\n\
-This version was built without expat.\n"),
- basename (program_name)));
- exit (EXIT_FAILURE);
- }
-}
diff --git a/gettext-tools/src/x-gsettings.h b/gettext-tools/src/x-gsettings.h
index 3c1a342..00b968c 100644
--- a/gettext-tools/src/x-gsettings.h
+++ b/gettext-tools/src/x-gsettings.h
@@ -28,17 +28,13 @@ extern "C" {
#endif
-#define EXTENSIONS_GSETTINGS \
- { "gschema.xml", "gsettings" }, \
+/* The scanner is implemented as ITS rules, in its/gsettings.its. */
-#define SCANNERS_GSETTINGS \
- { "gsettings", extract_gsettings, NULL, NULL, NULL, NULL }, \
+#define EXTENSIONS_GSETTINGS \
+ { "gschema.xml", NULL }, \
-/* Scan a gsettings XML file and add its translatable strings to mdlp. */
-extern void extract_gsettings (FILE *fp, const char *real_filename,
- const char *logical_filename,
- flag_context_list_table_ty *flag_table,
- msgdomain_list_ty *mdlp);
+#define SCANNERS_GSETTINGS \
+ { "gsettings", NULL, NULL, NULL, NULL, NULL }, \
#ifdef __cplusplus