(root)/
gettext-0.22.4/
gettext-tools/
src/
message.h
       1  /* GNU gettext - internationalization aids
       2     Copyright (C) 1995-1998, 2000-2010, 2012-2013, 2015-2016, 2019-2020, 2023 Free Software Foundation, Inc.
       3  
       4     This file was written by Peter Miller <millerp@canb.auug.org.au>
       5  
       6     This program is free software: you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3 of the License, or
       9     (at your option) any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      18  
      19  #ifndef _MESSAGE_H
      20  #define _MESSAGE_H
      21  
      22  #include "str-list.h"
      23  #include "pos.h"
      24  #include "mem-hash-map.h"
      25  
      26  #include <stdbool.h>
      27  
      28  
      29  #ifdef __cplusplus
      30  extern "C" {
      31  #endif
      32  
      33  
      34  /* According to Sun's Uniforum proposal the default message domain is
      35     named 'messages'.  */
      36  #define MESSAGE_DOMAIN_DEFAULT "messages"
      37  
      38  
      39  /* Separator between msgctxt and msgid in .mo files.  */
      40  #define MSGCTXT_SEPARATOR '\004'  /* EOT */
      41  
      42  
      43  /* Kinds of format strings.  */
      44  enum format_type
      45  {
      46    format_c,
      47    format_objc,
      48    format_cplusplus_brace,
      49    format_python,
      50    format_python_brace,
      51    format_java,
      52    format_java_printf,
      53    format_csharp,
      54    format_javascript,
      55    format_scheme,
      56    format_lisp,
      57    format_elisp,
      58    format_librep,
      59    format_ruby,
      60    format_sh,
      61    format_awk,
      62    format_lua,
      63    format_pascal,
      64    format_smalltalk,
      65    format_qt,
      66    format_qt_plural,
      67    format_kde,
      68    format_kde_kuit,
      69    format_boost,
      70    format_tcl,
      71    format_perl,
      72    format_perl_brace,
      73    format_php,
      74    format_gcc_internal,
      75    format_gfc_internal,
      76    format_ycp
      77  };
      78  #define NFORMATS 31     /* Number of format_type enum values.  */
      79  extern DLL_VARIABLE const char *const format_language[NFORMATS];
      80  extern DLL_VARIABLE const char *const format_language_pretty[NFORMATS];
      81  
      82  /* Is current msgid a format string?  */
      83  enum is_format
      84  {
      85    undecided,
      86    yes,
      87    no,
      88    yes_according_to_context,
      89    possible,
      90    impossible
      91  };
      92  
      93  extern bool
      94         possible_format_p (enum is_format);
      95  
      96  
      97  /* Range of an unsigned integer argument.  */
      98  struct argument_range
      99  {
     100    int min;
     101    int max;
     102  };
     103  
     104  /* Tests whether a range is present.  */
     105  #define has_range_p(range)  ((range).min >= 0 && (range).max >= 0)
     106  
     107  
     108  /* Is current msgid wrappable?  */
     109  #if 0
     110  enum is_wrap
     111  {
     112    undecided,
     113    yes,
     114    no
     115  };
     116  #else /* HACK - C's enum concept is so stupid */
     117  #define is_wrap is_format
     118  #endif
     119  
     120  
     121  /* Kinds of syntax checks which apply to strings.  */
     122  enum syntax_check_type
     123  {
     124    sc_ellipsis_unicode,
     125    sc_space_ellipsis,
     126    sc_quote_unicode,
     127    sc_bullet_unicode
     128  };
     129  #define NSYNTAXCHECKS 4
     130  extern DLL_VARIABLE const char *const syntax_check_name[NSYNTAXCHECKS];
     131  
     132  /* Is current msgid subject to a syntax check?  */
     133  #if 0
     134  enum is_syntax_check
     135  {
     136    undecided,
     137    yes,
     138    no
     139  };
     140  #else /* HACK - C's enum concept is so stupid */
     141  #define is_syntax_check is_format
     142  #endif
     143  
     144  
     145  struct altstr
     146  {
     147    const char *msgstr;
     148    size_t msgstr_len;
     149    const char *msgstr_end;
     150    string_list_ty *comment;
     151    string_list_ty *comment_dot;
     152    char *id;
     153  };
     154  
     155  
     156  typedef struct message_ty message_ty;
     157  struct message_ty
     158  {
     159    /* The msgctxt string, if present.  */
     160    const char *msgctxt;
     161  
     162    /* The msgid string.  */
     163    const char *msgid;
     164  
     165    /* The msgid's plural, if present.  */
     166    const char *msgid_plural;
     167  
     168    /* The msgstr strings.  */
     169    const char *msgstr;
     170    /* The number of bytes in msgstr, including the terminating NUL.  */
     171    size_t msgstr_len;
     172  
     173    /* Position in the source PO file.  */
     174    lex_pos_ty pos;
     175  
     176    /* Plain comments (#) appearing before the message.  */
     177    string_list_ty *comment;
     178  
     179    /* Extracted comments (#.) appearing before the message.  */
     180    string_list_ty *comment_dot;
     181  
     182    /* File position comments (#:) appearing before the message, one for
     183       each unique file position instance, sorted by file name and then
     184       by line.  */
     185    size_t filepos_count;
     186    lex_pos_ty *filepos;
     187  
     188    /* Informations from special comments (#,).
     189       Some of them come from extracted comments.  They are manipulated by
     190       the tools, e.g. msgmerge.  */
     191  
     192    /* Fuzzy means "needs translator review".  */
     193    bool is_fuzzy;
     194  
     195    /* Designation of format string syntax requirements for specific
     196       programming languages.  */
     197    enum is_format is_format[NFORMATS];
     198  
     199    /* Lower and upper bound for the argument whose format directive can be
     200       omitted in specific cases of singular or plural.  */
     201    struct argument_range range;
     202  
     203    /* Do we want the string to be wrapped in the emitted PO file?  */
     204    enum is_wrap do_wrap;
     205  
     206    /* Do we want to apply extra syntax checks on the string?  */
     207    enum is_syntax_check do_syntax_check[NSYNTAXCHECKS];
     208  
     209    /* The prev_msgctxt, prev_msgid and prev_msgid_plural strings appearing
     210       before the message, if present.  Generated by msgmerge.  */
     211    const char *prev_msgctxt;
     212    const char *prev_msgid;
     213    const char *prev_msgid_plural;
     214  
     215    /* If set the message is obsolete and while writing out it should be
     216       commented out.  */
     217    bool obsolete;
     218  
     219    /* Used for checking that messages have been used, in the msgcmp,
     220       msgmerge, msgcomm and msgcat programs.  */
     221    int used;
     222  
     223    /* Used for looking up the target message, in the msgcat program.  */
     224    message_ty *tmp;
     225  
     226    /* Used for combining alternative translations, in the msgcat program.  */
     227    int alternative_count;
     228    struct altstr *alternative;
     229  };
     230  
     231  extern message_ty *
     232         message_alloc (const char *msgctxt,
     233                        const char *msgid, const char *msgid_plural,
     234                        const char *msgstr, size_t msgstr_len,
     235                        const lex_pos_ty *pp);
     236  #define is_header(mp) ((mp)->msgctxt == NULL && (mp)->msgid[0] == '\0')
     237  extern void
     238         message_free (message_ty *mp);
     239  extern void
     240         message_comment_append (message_ty *mp, const char *comment);
     241  extern void
     242         message_comment_dot_append (message_ty *mp, const char *comment);
     243  extern void
     244         message_comment_filepos (message_ty *mp, const char *name, size_t line);
     245  extern message_ty *
     246         message_copy (message_ty *mp);
     247  
     248  
     249  typedef struct message_list_ty message_list_ty;
     250  struct message_list_ty
     251  {
     252    message_ty **item;
     253    size_t nitems;
     254    size_t nitems_max;
     255    bool use_hashtable;
     256    hash_table htable;    /* Table mapping msgid to 'message_ty *'.  */
     257  };
     258  
     259  /* Create a fresh message list.
     260     If USE_HASHTABLE is true, a hash table will be used to speed up
     261     message_list_search().  USE_HASHTABLE can only be set to true if it is
     262     known that the message list will not contain duplicate msgids.  */
     263  extern message_list_ty *
     264         message_list_alloc (bool use_hashtable);
     265  /* Free a message list.
     266     If keep_messages = 0, also free the messages.  If keep_messages = 1, don't
     267     free the messages.  */
     268  extern void
     269         message_list_free (message_list_ty *mlp, int keep_messages);
     270  extern void
     271         message_list_append (message_list_ty *mlp, message_ty *mp);
     272  extern void
     273         message_list_prepend (message_list_ty *mlp, message_ty *mp);
     274  extern void
     275         message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp);
     276  extern void
     277         message_list_delete_nth (message_list_ty *mlp, size_t n);
     278  typedef bool message_predicate_ty (const message_ty *mp);
     279  extern void
     280         message_list_remove_if_not (message_list_ty *mlp,
     281                                     message_predicate_ty *predicate);
     282  /* Recompute the hash table of a message list after the msgids or msgctxts
     283     changed.  */
     284  extern bool
     285         message_list_msgids_changed (message_list_ty *mlp);
     286  /* Copy a message list.
     287     If copy_level = 0, also copy the messages.  If copy_level = 1, share the
     288     messages.  */
     289  extern message_list_ty *
     290         message_list_copy (message_list_ty *mlp, int copy_level);
     291  extern message_ty *
     292         message_list_search (message_list_ty *mlp,
     293                              const char *msgctxt, const char *msgid);
     294  /* Return the message in MLP which maximizes the fuzzy_search_goal_function.
     295     Only messages with a fuzzy_search_goal_function > FUZZY_THRESHOLD are
     296     considered.  In case of several messages with the same goal function value,
     297     the one with the smaller index is returned.  */
     298  extern message_ty *
     299         message_list_search_fuzzy (message_list_ty *mlp,
     300                                    const char *msgctxt, const char *msgid);
     301  
     302  
     303  typedef struct message_list_list_ty message_list_list_ty;
     304  struct message_list_list_ty
     305  {
     306    message_list_ty **item;
     307    size_t nitems;
     308    size_t nitems_max;
     309  };
     310  
     311  extern message_list_list_ty *
     312         message_list_list_alloc (void);
     313  /* Free a list of message lists.
     314     If keep_level = 0, also free the messages.  If keep_level = 1, don't free
     315     the messages but free the lists.  If keep_level = 2, don't free the
     316     the messages and the lists.  */
     317  extern void
     318         message_list_list_free (message_list_list_ty *mllp, int keep_level);
     319  extern void
     320         message_list_list_append (message_list_list_ty *mllp,
     321                                   message_list_ty *mlp);
     322  extern void
     323         message_list_list_append_list (message_list_list_ty *mllp,
     324                                        message_list_list_ty *mllp2);
     325  extern message_ty *
     326         message_list_list_search (message_list_list_ty *mllp,
     327                                   const char *msgctxt, const char *msgid);
     328  extern message_ty *
     329         message_list_list_search_fuzzy (message_list_list_ty *mllp,
     330                                         const char *msgctxt, const char *msgid);
     331  
     332  
     333  typedef struct msgdomain_ty msgdomain_ty;
     334  struct msgdomain_ty
     335  {
     336    const char *domain;
     337    message_list_ty *messages;
     338  };
     339  
     340  extern msgdomain_ty *
     341         msgdomain_alloc (const char *domain, bool use_hashtable);
     342  extern void
     343         msgdomain_free (msgdomain_ty *mdp);
     344  
     345  
     346  typedef struct msgdomain_list_ty msgdomain_list_ty;
     347  struct msgdomain_list_ty
     348  {
     349    msgdomain_ty **item;
     350    size_t nitems;
     351    size_t nitems_max;
     352    bool use_hashtable;
     353    const char *encoding;         /* canonicalized encoding or NULL if unknown */
     354  };
     355  
     356  extern msgdomain_list_ty *
     357         msgdomain_list_alloc (bool use_hashtable);
     358  extern void
     359         msgdomain_list_free (msgdomain_list_ty *mdlp);
     360  extern void
     361         msgdomain_list_append (msgdomain_list_ty *mdlp, msgdomain_ty *mdp);
     362  extern void
     363         msgdomain_list_append_list (msgdomain_list_ty *mdlp,
     364                                     msgdomain_list_ty *mdlp2);
     365  extern message_list_ty *
     366         msgdomain_list_sublist (msgdomain_list_ty *mdlp, const char *domain,
     367                                 bool create);
     368  /* Copy a message domain list.
     369     If copy_level = 0, also copy the messages.  If copy_level = 1, share the
     370     messages but copy the domains.  If copy_level = 2, share the domains.  */
     371  extern msgdomain_list_ty *
     372         msgdomain_list_copy (msgdomain_list_ty *mdlp, int copy_level);
     373  extern message_ty *
     374         msgdomain_list_search (msgdomain_list_ty *mdlp,
     375                                const char *msgctxt, const char *msgid);
     376  extern message_ty *
     377         msgdomain_list_search_fuzzy (msgdomain_list_ty *mdlp,
     378                                      const char *msgctxt, const char *msgid);
     379  
     380  
     381  /* The goal function used in fuzzy search.
     382     Higher values indicate a closer match.
     383     If the result is < LOWER_BOUND, an arbitrary other value < LOWER_BOUND can
     384     be returned.  */
     385  extern double
     386         fuzzy_search_goal_function (const message_ty *mp,
     387                                     const char *msgctxt, const char *msgid,
     388                                     double lower_bound);
     389  
     390  /* The threshold for fuzzy-searching.
     391     A message is considered only if
     392     fuzzy_search_goal_function (mp, given, 0.0) > FUZZY_THRESHOLD.  */
     393  #define FUZZY_THRESHOLD 0.6
     394  
     395  
     396  #ifdef __cplusplus
     397  }
     398  #endif
     399  
     400  
     401  #endif /* message.h */