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@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
31extern "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.  */
45enum 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.  */
70extern DLL_VARIABLE const char *const format_language[NFORMATS];
71extern DLL_VARIABLE const char *const format_language_pretty[NFORMATS];
72
73/* Is current msgid a format string?  */
74enum is_format
75{
76  undecided,
77  yes,
78  no,
79  yes_according_to_context,
80  possible,
81  impossible
82};
83
84extern bool
85       possible_format_p (enum is_format);
86
87
88/* Is current msgid wrappable?  */
89#if 0
90enum 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
101typedef struct message_ty message_ty;
102struct 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
171extern 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')
177extern void
178       message_free (message_ty *mp);
179extern void
180       message_comment_append (message_ty *mp, const char *comment);
181extern void
182       message_comment_dot_append (message_ty *mp, const char *comment);
183extern void
184       message_comment_filepos (message_ty *mp, const char *name, size_t line);
185extern message_ty *
186       message_copy (message_ty *mp);
187
188
189typedef struct message_list_ty message_list_ty;
190struct 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.  */
203extern 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.  */
208extern void
209       message_list_free (message_list_ty *mlp, int keep_messages);
210extern void
211       message_list_append (message_list_ty *mlp, message_ty *mp);
212extern void
213       message_list_prepend (message_list_ty *mlp, message_ty *mp);
214extern void
215       message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp);
216extern void
217       message_list_delete_nth (message_list_ty *mlp, size_t n);
218typedef bool message_predicate_ty (const message_ty *mp);
219extern 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.  */
224extern bool
225       message_list_msgids_changed (message_list_ty *mlp);
226extern message_ty *
227       message_list_search (message_list_ty *mlp,
228			    const char *msgctxt, const char *msgid);
229extern message_ty *
230       message_list_search_fuzzy (message_list_ty *mlp,
231				  const char *msgctxt, const char *msgid);
232
233
234typedef struct message_list_list_ty message_list_list_ty;
235struct message_list_list_ty
236{
237  message_list_ty **item;
238  size_t nitems;
239  size_t nitems_max;
240};
241
242extern 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.  */
248extern void
249       message_list_list_free (message_list_list_ty *mllp, int keep_level);
250extern void
251       message_list_list_append (message_list_list_ty *mllp,
252				 message_list_ty *mlp);
253extern void
254       message_list_list_append_list (message_list_list_ty *mllp,
255				      message_list_list_ty *mllp2);
256extern message_ty *
257       message_list_list_search (message_list_list_ty *mllp,
258				 const char *msgctxt, const char *msgid);
259extern message_ty *
260       message_list_list_search_fuzzy (message_list_list_ty *mllp,
261				       const char *msgctxt, const char *msgid);
262
263
264typedef struct msgdomain_ty msgdomain_ty;
265struct msgdomain_ty
266{
267  const char *domain;
268  message_list_ty *messages;
269};
270
271extern msgdomain_ty *
272       msgdomain_alloc (const char *domain, bool use_hashtable);
273extern void
274       msgdomain_free (msgdomain_ty *mdp);
275
276
277typedef struct msgdomain_list_ty msgdomain_list_ty;
278struct 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
287extern msgdomain_list_ty *
288       msgdomain_list_alloc (bool use_hashtable);
289extern void
290       msgdomain_list_free (msgdomain_list_ty *mdlp);
291extern void
292       msgdomain_list_append (msgdomain_list_ty *mdlp, msgdomain_ty *mdp);
293extern void
294       msgdomain_list_append_list (msgdomain_list_ty *mdlp,
295				   msgdomain_list_ty *mdlp2);
296extern message_list_ty *
297       msgdomain_list_sublist (msgdomain_list_ty *mdlp, const char *domain,
298			       bool create);
299extern message_ty *
300       msgdomain_list_search (msgdomain_list_ty *mdlp,
301			      const char *msgctxt, const char *msgid);
302extern 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.  */
309extern 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