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