diff options
author | Daiki Ueno <ueno@gnu.org> | 2015-10-02 12:38:14 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2015-12-04 13:02:40 +0900 |
commit | 0daa0c191f18a1cdfd0cf7afa87d0891d11b1228 (patch) | |
tree | c1c1c891bd433ddc5fb9fb1af042c4c4e1eb41c1 | |
parent | 95d20e87121549fc014e25dbcd1e417f31f5344e (diff) | |
download | external_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.
-rw-r--r-- | gettext-tools/its/Makefile.am | 2 | ||||
-rw-r--r-- | gettext-tools/its/gsettings.its | 14 | ||||
-rw-r--r-- | gettext-tools/its/gsettings.loc | 6 | ||||
-rw-r--r-- | gettext-tools/src/Makefile.am | 2 | ||||
-rw-r--r-- | gettext-tools/src/x-gsettings.c | 387 | ||||
-rw-r--r-- | gettext-tools/src/x-gsettings.h | 14 |
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 |