Home | History | Annotate | Line # | Download | only in src
      1 /* GNU gettext - internationalization aids
      2    Copyright (C) 1995-1998, 2000-2006 Free Software Foundation, Inc.
      3 
      4    This file was written by Peter Miller <millerp (at) 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 2, or (at your option)
      9    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, write to the Free Software Foundation,
     18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
     19 
     20 #ifndef _MESSAGE_H
     21 #define _MESSAGE_H
     22 
     23 #include "str-list.h"
     24 #include "pos.h"
     25 #include "hash.h"
     26 
     27 #include <stdbool.h>
     28 
     29 
     30 #ifdef __cplusplus
     31 extern "C" {
     32 #endif
     33 
     34 
     35 /* According to Sun's Uniforum proposal the default message domain is
     36    named 'messages'.  */
     37 #define MESSAGE_DOMAIN_DEFAULT "messages"
     38 
     39 
     40 /* Separator between msgctxt and msgid in .mo files.  */
     41 #define MSGCTXT_SEPARATOR '\004'  /* EOT */
     42 
     43 
     44 /* Kinds of format strings.  */
     45 enum format_type
     46 {
     47   format_c,
     48   format_objc,
     49   format_sh,
     50   format_python,
     51   format_lisp,
     52   format_elisp,
     53   format_librep,
     54   format_scheme,
     55   format_smalltalk,
     56   format_java,
     57   format_csharp,
     58   format_awk,
     59   format_pascal,
     60   format_ycp,
     61   format_tcl,
     62   format_perl,
     63   format_perl_brace,
     64   format_php,
     65   format_gcc_internal,
     66   format_qt,
     67   format_boost
     68 };
     69 #define NFORMATS 21	/* Number of format_type enum values.  */
     70 extern DLL_VARIABLE const char *const format_language[NFORMATS];
     71 extern DLL_VARIABLE const char *const format_language_pretty[NFORMATS];
     72 
     73 /* Is current msgid a format string?  */
     74 enum is_format
     75 {
     76   undecided,
     77   yes,
     78   no,
     79   yes_according_to_context,
     80   possible,
     81   impossible
     82 };
     83 
     84 extern bool
     85        possible_format_p (enum is_format);
     86 
     87 
     88 /* Is current msgid wrappable?  */
     89 #if 0
     90 enum is_wrap
     91 {
     92   undecided,
     93   yes,
     94   no
     95 };
     96 #else /* HACK - C's enum concept is so stupid */
     97 #define is_wrap is_format
     98 #endif
     99 
    100 
    101 typedef struct message_ty message_ty;
    102 struct message_ty
    103 {
    104   /* The msgctxt string, if present.  */
    105   const char *msgctxt;
    106 
    107   /* The msgid string.  */
    108   const char *msgid;
    109 
    110   /* The msgid's plural, if present.  */
    111   const char *msgid_plural;
    112 
    113   /* The msgstr strings.  */
    114   const char *msgstr;
    115   /* The number of bytes in msgstr, including the terminating NUL.  */
    116   size_t msgstr_len;
    117 
    118   /* Position in the source PO file.  */
    119   lex_pos_ty pos;
    120 
    121   /* Plain comments (#) appearing before the message.  */
    122   string_list_ty *comment;
    123 
    124   /* Extracted comments (#.) appearing before the message.  */
    125   string_list_ty *comment_dot;
    126 
    127   /* File position comments (#:) appearing before the message, one for
    128      each unique file position instance, sorted by file name and then
    129      by line.  */
    130   size_t filepos_count;
    131   lex_pos_ty *filepos;
    132 
    133   /* Informations from special comments (e.g. generated by msgmerge).  */
    134   bool is_fuzzy;
    135   enum is_format is_format[NFORMATS];
    136 
    137   /* Do we want the string to be wrapped in the emitted PO file?  */
    138   enum is_wrap do_wrap;
    139 
    140   /* The prev_msgctxt, prev_msgid and prev_msgid_plural strings appearing
    141      before the message, if present.  Generated by msgmerge.  */
    142   const char *prev_msgctxt;
    143   const char *prev_msgid;
    144   const char *prev_msgid_plural;
    145 
    146   /* If set the message is obsolete and while writing out it should be
    147      commented out.  */
    148   bool obsolete;
    149 
    150   /* Used for checking that messages have been used, in the msgcmp,
    151      msgmerge, msgcomm and msgcat programs.  */
    152   int used;
    153 
    154   /* Used for looking up the target message, in the msgcat program.  */
    155   message_ty *tmp;
    156 
    157   /* Used for combining alternative translations, in the msgcat program.  */
    158   int alternative_count;
    159   struct altstr
    160     {
    161       const char *msgstr;
    162       size_t msgstr_len;
    163       const char *msgstr_end;
    164       string_list_ty *comment;
    165       string_list_ty *comment_dot;
    166       char *id;
    167     }
    168     *alternative;
    169 };
    170 
    171 extern message_ty *
    172        message_alloc (const char *msgctxt,
    173 		      const char *msgid, const char *msgid_plural,
    174 		      const char *msgstr, size_t msgstr_len,
    175 		      const lex_pos_ty *pp);
    176 #define is_header(mp) ((mp)->msgctxt == NULL && (mp)->msgid[0] == '\0')
    177 extern void
    178        message_free (message_ty *mp);
    179 extern void
    180        message_comment_append (message_ty *mp, const char *comment);
    181 extern void
    182        message_comment_dot_append (message_ty *mp, const char *comment);
    183 extern void
    184        message_comment_filepos (message_ty *mp, const char *name, size_t line);
    185 extern message_ty *
    186        message_copy (message_ty *mp);
    187 
    188 
    189 typedef struct message_list_ty message_list_ty;
    190 struct message_list_ty
    191 {
    192   message_ty **item;
    193   size_t nitems;
    194   size_t nitems_max;
    195   bool use_hashtable;
    196   hash_table htable;	/* Table mapping msgid to 'message_ty *'.  */
    197 };
    198 
    199 /* Create a fresh message list.
    200    If USE_HASHTABLE is true, a hash table will be used to speed up
    201    message_list_search().  USE_HASHTABLE can only be set to true if it is
    202    known that the message list will not contain duplicate msgids.  */
    203 extern message_list_ty *
    204        message_list_alloc (bool use_hashtable);
    205 /* Free a message list.
    206    If keep_messages = 0, also free the messages.  If keep_messages = 1, don't
    207    free the messages.  */
    208 extern void
    209        message_list_free (message_list_ty *mlp, int keep_messages);
    210 extern void
    211        message_list_append (message_list_ty *mlp, message_ty *mp);
    212 extern void
    213        message_list_prepend (message_list_ty *mlp, message_ty *mp);
    214 extern void
    215        message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp);
    216 extern void
    217        message_list_delete_nth (message_list_ty *mlp, size_t n);
    218 typedef bool message_predicate_ty (const message_ty *mp);
    219 extern void
    220        message_list_remove_if_not (message_list_ty *mlp,
    221 				   message_predicate_ty *predicate);
    222 /* Recompute the hash table of a message list after the msgids or msgctxts
    223    changed.  */
    224 extern bool
    225        message_list_msgids_changed (message_list_ty *mlp);
    226 extern message_ty *
    227        message_list_search (message_list_ty *mlp,
    228 			    const char *msgctxt, const char *msgid);
    229 extern message_ty *
    230        message_list_search_fuzzy (message_list_ty *mlp,
    231 				  const char *msgctxt, const char *msgid);
    232 
    233 
    234 typedef struct message_list_list_ty message_list_list_ty;
    235 struct message_list_list_ty
    236 {
    237   message_list_ty **item;
    238   size_t nitems;
    239   size_t nitems_max;
    240 };
    241 
    242 extern message_list_list_ty *
    243        message_list_list_alloc (void);
    244 /* Free a list of message lists.
    245    If keep_level = 0, also free the messages.  If keep_level = 1, don't free
    246    the messages but free the lists.  If keep_level = 2, don't free the
    247    the messages and the lists.  */
    248 extern void
    249        message_list_list_free (message_list_list_ty *mllp, int keep_level);
    250 extern void
    251        message_list_list_append (message_list_list_ty *mllp,
    252 				 message_list_ty *mlp);
    253 extern void
    254        message_list_list_append_list (message_list_list_ty *mllp,
    255 				      message_list_list_ty *mllp2);
    256 extern message_ty *
    257        message_list_list_search (message_list_list_ty *mllp,
    258 				 const char *msgctxt, const char *msgid);
    259 extern message_ty *
    260        message_list_list_search_fuzzy (message_list_list_ty *mllp,
    261 				       const char *msgctxt, const char *msgid);
    262 
    263 
    264 typedef struct msgdomain_ty msgdomain_ty;
    265 struct msgdomain_ty
    266 {
    267   const char *domain;
    268   message_list_ty *messages;
    269 };
    270 
    271 extern msgdomain_ty *
    272        msgdomain_alloc (const char *domain, bool use_hashtable);
    273 extern void
    274        msgdomain_free (msgdomain_ty *mdp);
    275 
    276 
    277 typedef struct msgdomain_list_ty msgdomain_list_ty;
    278 struct msgdomain_list_ty
    279 {
    280   msgdomain_ty **item;
    281   size_t nitems;
    282   size_t nitems_max;
    283   bool use_hashtable;
    284   const char *encoding;		/* canonicalized encoding or NULL if unknown */
    285 };
    286 
    287 extern msgdomain_list_ty *
    288        msgdomain_list_alloc (bool use_hashtable);
    289 extern void
    290        msgdomain_list_free (msgdomain_list_ty *mdlp);
    291 extern void
    292        msgdomain_list_append (msgdomain_list_ty *mdlp, msgdomain_ty *mdp);
    293 extern void
    294        msgdomain_list_append_list (msgdomain_list_ty *mdlp,
    295 				   msgdomain_list_ty *mdlp2);
    296 extern message_list_ty *
    297        msgdomain_list_sublist (msgdomain_list_ty *mdlp, const char *domain,
    298 			       bool create);
    299 extern message_ty *
    300        msgdomain_list_search (msgdomain_list_ty *mdlp,
    301 			      const char *msgctxt, const char *msgid);
    302 extern message_ty *
    303        msgdomain_list_search_fuzzy (msgdomain_list_ty *mdlp,
    304 				    const char *msgctxt, const char *msgid);
    305 
    306 
    307 /* The goal function used in fuzzy search.
    308    Higher values indicate a closer match.  */
    309 extern double
    310        fuzzy_search_goal_function (const message_ty *mp,
    311 				   const char *msgctxt, const char *msgid);
    312 
    313 /* The threshold for fuzzy-searching.
    314    A message is considered only if  fstrcmp (msg, given) > FUZZY_THRESHOLD.  */
    315 #define FUZZY_THRESHOLD 0.6
    316 #define FUZZY_THRESHOLD_INV 2
    317 
    318 
    319 #ifdef __cplusplus
    320 }
    321 #endif
    322 
    323 
    324 #endif /* message.h */
    325