]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Revisit the locating-rule code.
authorBruno Haible <bruno@clisp.org>
Thu, 25 Jul 2024 11:57:56 +0000 (13:57 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 25 Jul 2024 12:01:42 +0000 (14:01 +0200)
* gettext-tools/src/search-path.c: Reorder definitions. Add comments.
(get_search_path): Use XNMALLOC instead of XCALLOC. Verify the memory
allocation.
* gettext-tools/src/locating-rule.h: Add comments.
(locating_rule_list_locate): Add const to first argument.
* gettext-tools/src/locating-rule.c: Add comments.
(locating_rule_list_locate): Add const to first argument.
* gettext-tools/src/FILES: Update.
* gettext-tools/doc/gettext.texi (Preparing ITS Rules): Fix a typo.

gettext-tools/doc/gettext.texi
gettext-tools/src/FILES
gettext-tools/src/locating-rule.c
gettext-tools/src/locating-rule.h
gettext-tools/src/search-path.c

index 5bfc9691452766e95876280bf02ea9317b9c4fb3..bec8b4f83f3b5b5334b12c81aaaa50cfdbf3e747 100644 (file)
@@ -79,7 +79,7 @@ This file provides documentation for GNU @code{gettext} utilities.
 It also serves as a reference for the free Translation Project.
 
 @copying
-Copyright (C) 1995-1998, 2001-2023 Free Software Foundation, Inc.
+Copyright (C) 1995-1998, 2001-2024 Free Software Foundation, Inc.
 
 This manual is free documentation.  It is dually licensed under the
 GNU FDL and the GNU GPL.  This means that you can redistribute this
@@ -114,7 +114,7 @@ A copy of the license is included in @ref{GNU GPL}.
 @page
 @vskip 0pt plus 1filll
 @c @insertcopying
-Copyright (C) 1995-1998, 2001-2023 Free Software Foundation, Inc.
+Copyright (C) 1995-1998, 2001-2024 Free Software Foundation, Inc.
 
 This manual is free documentation.  It is dually licensed under the
 GNU FDL and the GNU GPL.  This means that you can redistribute this
@@ -10436,7 +10436,7 @@ where the translated strings are directly consumed by programs, and the
 other is the case where the translated strings are merged back to the
 original XML document.  In the former case, special characters in the
 extracted strings shouldn't be escaped, while they should in the latter
-case.  To control wheter to escape special characters, the @samp{Escape
+case.  To control whether to escape special characters, the @samp{Escape
 Special Characters} data category can be used.
 
 To merge the translations, the @samp{msgfmt} program can be used with
index 47b29bd12a8d6d6bfc60e81a14820395a854615f..47060304164e330785c02f5ff194ec7490fc553c 100644 (file)
@@ -263,6 +263,19 @@ msgl-check.h
 msgl-check.c
                 Checking of messages.
 
++-------------- Internationalization of XML files
+| search-path.h
+| search-path.c
+|               Search path for locating *.loc and *.its files.
+| locating-rule.h
+| locating-rule.c
+|               Determining the appropriate *.its file for a given input.
+| its.h
+| its.c
+|               Internationalization Tag Set: Interpretation of a *.its file
+|               for processing an XML file.
++-------------- Internationalization of XML files
+
 +-------------- The 'msgfmt' program
 | msgfmt.h
 |               Declarations.
@@ -402,7 +415,6 @@ msgl-check.c
 | x-glade.c
 |               String extractor from .glade files, GNOME GUI descriptions.
 | x-gsettings.h
-| x-gsettings.c
 |               String extractor for GSettings schema file.
 | x-appdata.h
 | x-appdata.c
index 214787625f9d1374fb301e69ccb306013d6a0d15..1c34355c760285ed43c40fb690cb27472d0e58e4 100644 (file)
@@ -43,6 +43,9 @@
 
 #define LOCATING_RULES_NS "https://www.gnu.org/s/gettext/ns/locating-rules/1.0"
 
+/* This type represents a <documentRule> element, such as
+     <documentRule localName="GTK-Interface" target="glade1.its"/>
+   The attributes 'ns' and 'localName' are optional; 'target' is mandatory.  */
 struct document_locating_rule_ty
 {
   char *ns;
@@ -51,13 +54,22 @@ struct document_locating_rule_ty
   char *target;
 };
 
+/* This type represents a list of <documentRule> elements.  */
 struct document_locating_rule_list_ty
 {
   struct document_locating_rule_ty *items;
   size_t nitems;
+  /* nitems_max is the number of allocated elements.  nitems ≤ nitems_max.  */
   size_t nitems_max;
 };
 
+/* This type represents a <locatingRule> element, such as
+     <locatingRule name="Glade" pattern="*.glade">
+       <documentRule localName="GTK-Interface" target="glade1.its"/>
+       <documentRule localName="glade-interface" target="glade2.its"/>
+       <documentRule localName="interface" target="gtkbuilder.its"/>
+     </locatingRule>
+   The attribute 'name' is optional; 'pattern' is mandatory.  */
 struct locating_rule_ty
 {
   char *pattern;
@@ -67,10 +79,13 @@ struct locating_rule_ty
   char *target;
 };
 
+/* This type represents a list of <locatingRule> elements,
+   possibly from different *.loc files.  */
 struct locating_rule_list_ty
 {
   struct locating_rule_ty *items;
   size_t nitems;
+  /* nitems_max is the number of allocated elements.  nitems ≤ nitems_max.  */
   size_t nitems_max;
 };
 
@@ -194,7 +209,7 @@ locating_rule_match (struct locating_rule_ty *rule,
 }
 
 const char *
-locating_rule_list_locate (struct locating_rule_list_ty *rules,
+locating_rule_list_locate (const struct locating_rule_list_ty *rules,
                            const char *filename,
                            const char *name)
 {
index 7a6e2b3a899506dd72a9836c25d8bce045998819..48269e95389b49c3f2e793e52cff6173edb65927 100644 (file)
@@ -1,5 +1,5 @@
 /* XML resource locating rules
-   Copyright (C) 2015, 2018 Free Software Foundation, Inc.
+   Copyright (C) 2015-2024 Free Software Foundation, Inc.
 
    This file was written by Daiki Ueno <ueno@gnu.org>, 2015.
 
 extern "C" {
 #endif
 
+/* This file deals with how to find the ITS file for a given XML input.
+   The caller needs to supply the following information:
+     - The "language name", coming from xgettext's -L option or guessed
+       from the input file's extension.
+     - The XML file name.
+   After opening the XML file, we get the top-level XML element name;
+   this is called the 'localName'.
+
+   The its/ directory contains a set a *.loc files; these are all read
+   into memory and form a rule list.
+
+   For example, this piece of XML:
+
+     <locatingRule name="Glade" pattern="*.glade">
+       <documentRule localName="GTK-Interface" target="glade1.its"/>
+       <documentRule localName="glade-interface" target="glade2.its"/>
+       <documentRule localName="interface" target="gtkbuilder.its"/>
+     </locatingRule>
+     <locatingRule name="Glade" pattern="*.glade2">
+       <documentRule localName="glade-interface" target="glade2.its"/>
+     </locatingRule>
+     <locatingRule name="Glade" pattern="*.ui">
+       <documentRule localName="interface" target="gtkbuilder.its"/>
+     </locatingRule>
+     <locatingRule name="AppData" pattern="*.appdata.xml">
+       <documentRule localName="component" target="metainfo.its"/>
+     </locatingRule>
+
+   means:
+
+     - If the language is "Glade" or the file name matches "*.glade",
+       then look at the top-level XML element name:
+       - If it's <GTK-Interface>, use the file glade1.its.
+       - If it's <glade-interface>, use the file glade2.its.
+       - If it's <interface>, use the file gtkbuilder.its.
+     - If the language is "Glade" or the file name matches "*.glade2",
+       then look at the top-level XML element name:
+       - If it's <glade-interface>, use the file glade2.its.
+     - If the language is "Glade" or the file name matches "*.ui",
+       then look at the top-level XML element name:
+       - If it's <interface>, use the file gtkbuilder.its.
+     - If the language is "AppData" or the file name matches "*.appdata.xml",
+       then look at the top-level XML element name:
+       - If it's <component>, use the file metainfo.its.
+
+   See the documentation node "Preparing Rules for XML Internationalization".
+ */
+
+/* The 'locating_rule_list_ty *' type represents a locating rule list.  */
 typedef struct locating_rule_list_ty locating_rule_list_ty;
 
-/* Creates a fresh locating_rule_list_ty.  */
-extern struct locating_rule_list_ty *locating_rule_list_alloc (void);
+/* Creates a fresh locating_rule_list_ty and returns it.  */
+extern struct locating_rule_list_ty *
+       locating_rule_list_alloc (void);
 
+/* Adds all rules from all *.loc files in the given DIRECTORY to the RULES
+   object.  */
 extern bool
        locating_rule_list_add_from_directory (locating_rule_list_ty *rules,
                                               const char *directory);
 
-/* Determines the location of resource associated with FILENAME,
-   accoding to the loaded locating rules.  */
-extern const char *locating_rule_list_locate (locating_rule_list_ty *rules,
-                                              const char *filename,
-                                              const char *name);
+/* Determines the location of the .its file to be used for FILENAME,
+   when the "language name" is NAME (can be NULL if not provided),
+   accoding to the locating rules in the RULES object.
+   The result is just the base name of the .its file; the caller then
+   needs to find it, using "search-path.h".  */
+extern const char *
+       locating_rule_list_locate (const locating_rule_list_ty *rules,
+                                  const char *filename,
+                                  const char *name);
 
-/* Releases memory allocated for RULES.  */
-extern void locating_rule_list_free (locating_rule_list_ty *rules);
+/* Releases memory allocated for the RULES object.  */
+extern void
+       locating_rule_list_free (locating_rule_list_ty *rules);
 
 #ifdef __cplusplus
 }
index 0f1bc44469f44847bafbcff25545f4e07f646cb4..c12aeb09c574bdb250e5887055611b810dd087af 100644 (file)
@@ -1,5 +1,5 @@
 /* Routines for locating data files
-   Copyright (C) 2016, 2019 Free Software Foundation, Inc.
+   Copyright (C) 2016-2024 Free Software Foundation, Inc.
 
    This file was written by Daiki Ueno <ueno@gnu.org>, 2016.
 
 #include "xmemdup0.h"
 #include "xvasprintf.h"
 
-typedef void (* foreach_function_ty) (const char *dir, size_t len, void *data);
 
-struct path_array_ty {
-  char **ptr;
-  size_t len;
-  /* Transient argument for fill().  */
-  const char *sub;
-};
+/* This is a callback function from foreach_elements.
+   The argument is a directory name: DIR[0..LEN-1].
+   DATA is an opaque data pointer passed to foreach_elements.  */
+typedef void (* foreach_function_ty) (const char *dir, size_t len, void *data);
 
+/* Invoke FUNCTION on every non-empty element of DIRS.
+   DIRS is a colon-separated list of directory names.
+   DATA is an opaque data pointer that gets passed to FUNCTION.  */
 static void
 foreach_elements (const char *dirs, foreach_function_ty function, void *data)
 {
   const char *start = dirs;
 
-  /* Count the number of valid elements in DIRS.  */
+  /* Iterate through DIRS.  */
   while (*start != '\0')
     {
       char *end = strchrnul (start, ':');
@@ -62,6 +62,9 @@ foreach_elements (const char *dirs, foreach_function_ty function, void *data)
     }
 }
 
+
+/* Callback function that assumes that DATA is a (size_t *) and increments the
+   pointed value.  */
 static void
 increment (const char *dir, size_t len, void *data)
 {
@@ -69,11 +72,24 @@ increment (const char *dir, size_t len, void *data)
   (*count)++;
 }
 
+
+/* Data for the FILL callback function.  */
+struct path_array_ty {
+  char **ptr;
+  size_t len;
+  /* Transient argument for fill().  */
+  const char *sub;
+};
+
+/* Callback function that assumes that DATA is a (struct path_array_ty *) and
+   adds DIR[0..LEN-1] (or the same, with the SUB subdirectory appended) to
+   the path_array_ty.  */
 static void
 fill (const char *dir, size_t len, void *data)
 {
   struct path_array_ty *array = data;
-  char *base, *name;
+  char *base;
+  char *name;
 
   base = xmemdup0 (dir, len);
   if (array->sub == NULL)
@@ -87,6 +103,7 @@ fill (const char *dir, size_t len, void *data)
   array->ptr[array->len++] = name;
 }
 
+
 /* Find the standard search path for data files.  If SUB is not NULL, append it
    to each directory.
    Returns a freshly allocated NULL terminated list of freshly allocated
@@ -118,7 +135,7 @@ get_search_path (const char *sub)
     foreach_elements (xdgdatadirs, increment, &count);
 
   /* Allocate the array.  */
-  array.ptr = XCALLOC (count + 1, char *);
+  array.ptr = XNMALLOC (count + 1, char *);
   array.len = 0;
 
   /* Fill the array.  */
@@ -178,5 +195,12 @@ get_search_path (const char *sub)
     }
   }
 
+  /* Verify that COUNT was sufficient.  */
+  if (!(count <= array.len))
+    abort ();
+
+  /* Add a NULL at the end.  */
+  array.ptr[array.len] = NULL;
+
   return array.ptr;
 }