1/* GNU gettext - internationalization aids 2 Copyright (C) 1995-1998, 2000-2007 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 <http://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 "hash.h" 25 26#include <stdbool.h> 27 28 29#ifdef __cplusplus 30extern "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. */ 44enum format_type 45{ 46 format_c, 47 format_objc, 48 format_sh, 49 format_python, 50 format_lisp, 51 format_elisp, 52 format_librep, 53 format_scheme, 54 format_smalltalk, 55 format_java, 56 format_csharp, 57 format_awk, 58 format_pascal, 59 format_ycp, 60 format_tcl, 61 format_perl, 62 format_perl_brace, 63 format_php, 64 format_gcc_internal, 65 format_qt, 66 format_kde, 67 format_boost 68}; 69#define NFORMATS 22 /* 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 101struct altstr 102{ 103 const char *msgstr; 104 size_t msgstr_len; 105 const char *msgstr_end; 106 string_list_ty *comment; 107 string_list_ty *comment_dot; 108 char *id; 109}; 110 111 112typedef struct message_ty message_ty; 113struct message_ty 114{ 115 /* The msgctxt string, if present. */ 116 const char *msgctxt; 117 118 /* The msgid string. */ 119 const char *msgid; 120 121 /* The msgid's plural, if present. */ 122 const char *msgid_plural; 123 124 /* The msgstr strings. */ 125 const char *msgstr; 126 /* The number of bytes in msgstr, including the terminating NUL. */ 127 size_t msgstr_len; 128 129 /* Position in the source PO file. */ 130 lex_pos_ty pos; 131 132 /* Plain comments (#) appearing before the message. */ 133 string_list_ty *comment; 134 135 /* Extracted comments (#.) appearing before the message. */ 136 string_list_ty *comment_dot; 137 138 /* File position comments (#:) appearing before the message, one for 139 each unique file position instance, sorted by file name and then 140 by line. */ 141 size_t filepos_count; 142 lex_pos_ty *filepos; 143 144 /* Informations from special comments (e.g. generated by msgmerge). */ 145 bool is_fuzzy; 146 enum is_format is_format[NFORMATS]; 147 148 /* Do we want the string to be wrapped in the emitted PO file? */ 149 enum is_wrap do_wrap; 150 151 /* The prev_msgctxt, prev_msgid and prev_msgid_plural strings appearing 152 before the message, if present. Generated by msgmerge. */ 153 const char *prev_msgctxt; 154 const char *prev_msgid; 155 const char *prev_msgid_plural; 156 157 /* If set the message is obsolete and while writing out it should be 158 commented out. */ 159 bool obsolete; 160 161 /* Used for checking that messages have been used, in the msgcmp, 162 msgmerge, msgcomm and msgcat programs. */ 163 int used; 164 165 /* Used for looking up the target message, in the msgcat program. */ 166 message_ty *tmp; 167 168 /* Used for combining alternative translations, in the msgcat program. */ 169 int alternative_count; 170 struct altstr *alternative; 171}; 172 173extern message_ty * 174 message_alloc (const char *msgctxt, 175 const char *msgid, const char *msgid_plural, 176 const char *msgstr, size_t msgstr_len, 177 const lex_pos_ty *pp); 178#define is_header(mp) ((mp)->msgctxt == NULL && (mp)->msgid[0] == '\0') 179extern void 180 message_free (message_ty *mp); 181extern void 182 message_comment_append (message_ty *mp, const char *comment); 183extern void 184 message_comment_dot_append (message_ty *mp, const char *comment); 185extern void 186 message_comment_filepos (message_ty *mp, const char *name, size_t line); 187extern message_ty * 188 message_copy (message_ty *mp); 189 190 191typedef struct message_list_ty message_list_ty; 192struct message_list_ty 193{ 194 message_ty **item; 195 size_t nitems; 196 size_t nitems_max; 197 bool use_hashtable; 198 hash_table htable; /* Table mapping msgid to 'message_ty *'. */ 199}; 200 201/* Create a fresh message list. 202 If USE_HASHTABLE is true, a hash table will be used to speed up 203 message_list_search(). USE_HASHTABLE can only be set to true if it is 204 known that the message list will not contain duplicate msgids. */ 205extern message_list_ty * 206 message_list_alloc (bool use_hashtable); 207/* Free a message list. 208 If keep_messages = 0, also free the messages. If keep_messages = 1, don't 209 free the messages. */ 210extern void 211 message_list_free (message_list_ty *mlp, int keep_messages); 212extern void 213 message_list_append (message_list_ty *mlp, message_ty *mp); 214extern void 215 message_list_prepend (message_list_ty *mlp, message_ty *mp); 216extern void 217 message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp); 218extern void 219 message_list_delete_nth (message_list_ty *mlp, size_t n); 220typedef bool message_predicate_ty (const message_ty *mp); 221extern void 222 message_list_remove_if_not (message_list_ty *mlp, 223 message_predicate_ty *predicate); 224/* Recompute the hash table of a message list after the msgids or msgctxts 225 changed. */ 226extern bool 227 message_list_msgids_changed (message_list_ty *mlp); 228/* Copy a message list. 229 If copy_level = 0, also copy the messages. If copy_level = 1, share the 230 messages. */ 231extern message_list_ty * 232 message_list_copy (message_list_ty *mlp, int copy_level); 233extern message_ty * 234 message_list_search (message_list_ty *mlp, 235 const char *msgctxt, const char *msgid); 236extern message_ty * 237 message_list_search_fuzzy (message_list_ty *mlp, 238 const char *msgctxt, const char *msgid); 239 240 241typedef struct message_list_list_ty message_list_list_ty; 242struct message_list_list_ty 243{ 244 message_list_ty **item; 245 size_t nitems; 246 size_t nitems_max; 247}; 248 249extern message_list_list_ty * 250 message_list_list_alloc (void); 251/* Free a list of message lists. 252 If keep_level = 0, also free the messages. If keep_level = 1, don't free 253 the messages but free the lists. If keep_level = 2, don't free the 254 the messages and the lists. */ 255extern void 256 message_list_list_free (message_list_list_ty *mllp, int keep_level); 257extern void 258 message_list_list_append (message_list_list_ty *mllp, 259 message_list_ty *mlp); 260extern void 261 message_list_list_append_list (message_list_list_ty *mllp, 262 message_list_list_ty *mllp2); 263extern message_ty * 264 message_list_list_search (message_list_list_ty *mllp, 265 const char *msgctxt, const char *msgid); 266extern message_ty * 267 message_list_list_search_fuzzy (message_list_list_ty *mllp, 268 const char *msgctxt, const char *msgid); 269 270 271typedef struct msgdomain_ty msgdomain_ty; 272struct msgdomain_ty 273{ 274 const char *domain; 275 message_list_ty *messages; 276}; 277 278extern msgdomain_ty * 279 msgdomain_alloc (const char *domain, bool use_hashtable); 280extern void 281 msgdomain_free (msgdomain_ty *mdp); 282 283 284typedef struct msgdomain_list_ty msgdomain_list_ty; 285struct msgdomain_list_ty 286{ 287 msgdomain_ty **item; 288 size_t nitems; 289 size_t nitems_max; 290 bool use_hashtable; 291 const char *encoding; /* canonicalized encoding or NULL if unknown */ 292}; 293 294extern msgdomain_list_ty * 295 msgdomain_list_alloc (bool use_hashtable); 296extern void 297 msgdomain_list_free (msgdomain_list_ty *mdlp); 298extern void 299 msgdomain_list_append (msgdomain_list_ty *mdlp, msgdomain_ty *mdp); 300extern void 301 msgdomain_list_append_list (msgdomain_list_ty *mdlp, 302 msgdomain_list_ty *mdlp2); 303extern message_list_ty * 304 msgdomain_list_sublist (msgdomain_list_ty *mdlp, const char *domain, 305 bool create); 306/* Copy a message domain list. 307 If copy_level = 0, also copy the messages. If copy_level = 1, share the 308 messages but copy the domains. If copy_level = 2, share the domains. */ 309extern msgdomain_list_ty * 310 msgdomain_list_copy (msgdomain_list_ty *mdlp, int copy_level); 311extern message_ty * 312 msgdomain_list_search (msgdomain_list_ty *mdlp, 313 const char *msgctxt, const char *msgid); 314extern message_ty * 315 msgdomain_list_search_fuzzy (msgdomain_list_ty *mdlp, 316 const char *msgctxt, const char *msgid); 317 318 319/* The goal function used in fuzzy search. 320 Higher values indicate a closer match. */ 321extern double 322 fuzzy_search_goal_function (const message_ty *mp, 323 const char *msgctxt, const char *msgid); 324 325/* The threshold for fuzzy-searching. 326 A message is considered only if fstrcmp (msg, given) > FUZZY_THRESHOLD. */ 327#define FUZZY_THRESHOLD 0.6 328 329 330#ifdef __cplusplus 331} 332#endif 333 334 335#endif /* message.h */ 336