#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "message.h"
#include <stdlib.h>
#include <string.h>
#include "fstrcmp.h"
#include "hash.h"
#include "xalloc.h"
const char *const format_language[NFORMATS] =
{
"c",
"objc",
"sh",
"python",
"lisp",
"elisp",
"librep",
"smalltalk",
"java",
"awk",
"object-pascal",
"ycp",
"tcl",
"perl",
"perl-brace",
"php",
"gcc-internal",
"qt"
};
const char *const format_language_pretty[NFORMATS] =
{
"C",
"Objective C",
"Shell",
"Python",
"Lisp",
"Emacs Lisp",
"librep",
"Smalltalk",
"Java",
"awk",
"Object Pascal",
"YCP",
"Tcl",
"Perl",
"Perl brace",
"PHP",
"GCC internal",
"Qt"
};
bool
possible_format_p (enum is_format is_format)
{
return is_format == possible
|| is_format == yes_according_to_context
|| is_format == yes;
}
message_ty *
message_alloc (const char *msgid, const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
const lex_pos_ty *pp)
{
message_ty *mp;
size_t i;
mp = (message_ty *) xmalloc (sizeof (message_ty));
mp->msgid = msgid;
mp->msgid_plural = (msgid_plural != NULL ? xstrdup (msgid_plural) : NULL);
mp->msgstr = msgstr;
mp->msgstr_len = msgstr_len;
mp->pos = *pp;
mp->comment = NULL;
mp->comment_dot = NULL;
mp->filepos_count = 0;
mp->filepos = NULL;
mp->is_fuzzy = false;
for (i = 0; i < NFORMATS; i++)
mp->is_format[i] = undecided;
mp->do_wrap = undecided;
mp->used = 0;
mp->obsolete = false;
return mp;
}
void
message_free (message_ty *mp)
{
size_t j;
free ((char *) mp->msgid);
if (mp->msgid_plural != NULL)
free ((char *) mp->msgid_plural);
free ((char *) mp->msgstr);
if (mp->comment != NULL)
string_list_free (mp->comment);
if (mp->comment_dot != NULL)
string_list_free (mp->comment_dot);
for (j = 0; j < mp->filepos_count; ++j)
free ((char *) mp->filepos[j].file_name);
if (mp->filepos != NULL)
free (mp->filepos);
free (mp);
}
void
message_comment_append (message_ty *mp, const char *s)
{
if (mp->comment == NULL)
mp->comment = string_list_alloc ();
string_list_append (mp->comment, s);
}
void
message_comment_dot_append (message_ty *mp, const char *s)
{
if (mp->comment_dot == NULL)
mp->comment_dot = string_list_alloc ();
string_list_append (mp->comment_dot, s);
}
void
message_comment_filepos (message_ty *mp, const char *name, size_t line)
{
size_t j;
size_t nbytes;
lex_pos_ty *pp;
for (j = 0; j < mp->filepos_count; j++)
{
pp = &mp->filepos[j];
if (strcmp (pp->file_name, name) == 0 && pp->line_number == line)
return;
}
nbytes = (mp->filepos_count + 1) * sizeof (mp->filepos[0]);
mp->filepos = xrealloc (mp->filepos, nbytes);
pp = &mp->filepos[mp->filepos_count++];
pp->file_name = xstrdup (name);
pp->line_number = line;
}
message_ty *
message_copy (message_ty *mp)
{
message_ty *result;
size_t j, i;
result = message_alloc (xstrdup (mp->msgid), mp->msgid_plural,
mp->msgstr, mp->msgstr_len, &mp->pos);
if (mp->comment)
{
for (j = 0; j < mp->comment->nitems; ++j)
message_comment_append (result, mp->comment->item[j]);
}
if (mp->comment_dot)
{
for (j = 0; j < mp->comment_dot->nitems; ++j)
message_comment_dot_append (result, mp->comment_dot->item[j]);
}
result->is_fuzzy = mp->is_fuzzy;
for (i = 0; i < NFORMATS; i++)
result->is_format[i] = mp->is_format[i];
result->do_wrap = mp->do_wrap;
for (j = 0; j < mp->filepos_count; ++j)
{
lex_pos_ty *pp = &mp->filepos[j];
message_comment_filepos (result, pp->file_name, pp->line_number);
}
return result;
}
message_list_ty *
message_list_alloc (bool use_hashtable)
{
message_list_ty *mlp;
mlp = (message_list_ty *) xmalloc (sizeof (message_list_ty));
mlp->nitems = 0;
mlp->nitems_max = 0;
mlp->item = NULL;
if ((mlp->use_hashtable = use_hashtable))
init_hash (&mlp->htable, 10);
return mlp;
}
void
message_list_free (message_list_ty *mlp)
{
size_t j;
for (j = 0; j < mlp->nitems; ++j)
message_free (mlp->item[j]);
if (mlp->item)
free (mlp->item);
if (mlp->use_hashtable)
delete_hash (&mlp->htable);
free (mlp);
}
void
message_list_append (message_list_ty *mlp, message_ty *mp)
{
if (mlp->nitems >= mlp->nitems_max)
{
size_t nbytes;
mlp->nitems_max = mlp->nitems_max * 2 + 4;
nbytes = mlp->nitems_max * sizeof (message_ty *);
mlp->item = xrealloc (mlp->item, nbytes);
}
mlp->item[mlp->nitems++] = mp;
if (mlp->use_hashtable)
if (insert_entry (&mlp->htable, mp->msgid, strlen (mp->msgid) + 1, mp))
abort ();
}
void
message_list_prepend (message_list_ty *mlp, message_ty *mp)
{
size_t j;
if (mlp->nitems >= mlp->nitems_max)
{
size_t nbytes;
mlp->nitems_max = mlp->nitems_max * 2 + 4;
nbytes = mlp->nitems_max * sizeof (message_ty *);
mlp->item = xrealloc (mlp->item, nbytes);
}
for (j = mlp->nitems; j > 0; j--)
mlp->item[j] = mlp->item[j - 1];
mlp->item[0] = mp;
mlp->nitems++;
if (mlp->use_hashtable)
if (insert_entry (&mlp->htable, mp->msgid, strlen (mp->msgid) + 1, mp))
abort ();
}
#if 0
void
message_list_delete_nth (message_list_ty *mlp, size_t n)
{
size_t j;
if (n >= mlp->nitems)
return;
message_free (mlp->item[n]);
for (j = n + 1; j < mlp->nitems; ++j)
mlp->item[j - 1] = mlp->item[j];
mlp->nitems--;
if (mlp->use_hashtable)
{
delete_hash (&mlp->htable);
mlp->use_hashtable = false;
}
}
#endif
void
message_list_remove_if_not (message_list_ty *mlp,
message_predicate_ty *predicate)
{
size_t i, j;
for (j = 0, i = 0; j < mlp->nitems; j++)
if (predicate (mlp->item[j]))
mlp->item[i++] = mlp->item[j];
if (mlp->use_hashtable && i < mlp->nitems)
{
delete_hash (&mlp->htable);
mlp->use_hashtable = false;
}
mlp->nitems = i;
}
bool
message_list_msgids_changed (message_list_ty *mlp)
{
if (mlp->use_hashtable)
{
unsigned long int size = mlp->htable.size;
size_t j;
delete_hash (&mlp->htable);
init_hash (&mlp->htable, size);
for (j = 0; j < mlp->nitems; j++)
{
message_ty *mp = mlp->item[j];
if (insert_entry (&mlp->htable, mp->msgid, strlen (mp->msgid) + 1,
mp))
{
delete_hash (&mlp->htable);
mlp->use_hashtable = false;
return true;
}
}
}
return false;
}
message_ty *
message_list_search (message_list_ty *mlp, const char *msgid)
{
if (mlp->use_hashtable)
{
void *htable_value;
if (find_entry (&mlp->htable, msgid, strlen (msgid) + 1, &htable_value))
return NULL;
else
return (message_ty *) htable_value;
}
else
{
size_t j;
for (j = 0; j < mlp->nitems; ++j)
{
message_ty *mp;
mp = mlp->item[j];
if (strcmp (msgid, mp->msgid) == 0)
return mp;
}
return NULL;
}
}
static message_ty *
message_list_search_fuzzy_inner (message_list_ty *mlp, const char *msgid,
double *best_weight_p)
{
size_t j;
message_ty *best_mp;
best_mp = NULL;
for (j = 0; j < mlp->nitems; ++j)
{
message_ty *mp;
mp = mlp->item[j];
if (mp->msgstr != NULL && mp->msgstr[0] != '\0')
{
double weight = fstrcmp (msgid, mp->msgid);
if (weight > *best_weight_p)
{
*best_weight_p = weight;
best_mp = mp;
}
}
}
return best_mp;
}
message_ty *
message_list_search_fuzzy (message_list_ty *mlp, const char *msgid)
{
double best_weight;
best_weight = 0.6;
return message_list_search_fuzzy_inner (mlp, msgid, &best_weight);
}
message_list_list_ty *
message_list_list_alloc ()
{
message_list_list_ty *mllp;
mllp = (message_list_list_ty *) xmalloc (sizeof (message_list_list_ty));
mllp->nitems = 0;
mllp->nitems_max = 0;
mllp->item = NULL;
return mllp;
}
#if 0
void
message_list_list_free (message_list_list_ty *mllp)
{
size_t j;
for (j = 0; j < mllp->nitems; ++j)
message_list_free (mllp->item[j]);
if (mllp->item)
free (mllp->item);
free (mllp);
}
#endif
void
message_list_list_append (message_list_list_ty *mllp, message_list_ty *mlp)
{
if (mllp->nitems >= mllp->nitems_max)
{
size_t nbytes;
mllp->nitems_max = mllp->nitems_max * 2 + 4;
nbytes = mllp->nitems_max * sizeof (message_list_ty *);
mllp->item = xrealloc (mllp->item, nbytes);
}
mllp->item[mllp->nitems++] = mlp;
}
void
message_list_list_append_list (message_list_list_ty *mllp,
message_list_list_ty *mllp2)
{
size_t j;
for (j = 0; j < mllp2->nitems; ++j)
message_list_list_append (mllp, mllp2->item[j]);
}
message_ty *
message_list_list_search (message_list_list_ty *mllp, const char *msgid)
{
message_ty *best_mp;
int best_weight;
size_t j;
best_mp = NULL;
best_weight = 0;
for (j = 0; j < mllp->nitems; ++j)
{
message_list_ty *mlp;
message_ty *mp;
mlp = mllp->item[j];
mp = message_list_search (mlp, msgid);
if (mp)
{
int weight = (mp->msgstr_len == 1 && mp->msgstr[0] == '\0' ? 1 : 2);
if (weight > best_weight)
{
best_mp = mp;
best_weight = weight;
}
}
}
return best_mp;
}
message_ty *
message_list_list_search_fuzzy (message_list_list_ty *mllp, const char *msgid)
{
size_t j;
double best_weight;
message_ty *best_mp;
best_weight = 0.6;
best_mp = NULL;
for (j = 0; j < mllp->nitems; ++j)
{
message_list_ty *mlp;
message_ty *mp;
mlp = mllp->item[j];
mp = message_list_search_fuzzy_inner (mlp, msgid, &best_weight);
if (mp)
best_mp = mp;
}
return best_mp;
}
msgdomain_ty*
msgdomain_alloc (const char *domain, bool use_hashtable)
{
msgdomain_ty *mdp;
mdp = (msgdomain_ty *) xmalloc (sizeof (msgdomain_ty));
mdp->domain = domain;
mdp->messages = message_list_alloc (use_hashtable);
return mdp;
}
void
msgdomain_free (msgdomain_ty *mdp)
{
message_list_free (mdp->messages);
free (mdp);
}
msgdomain_list_ty *
msgdomain_list_alloc (bool use_hashtable)
{
msgdomain_list_ty *mdlp;
mdlp = (msgdomain_list_ty *) xmalloc (sizeof (msgdomain_list_ty));
mdlp->nitems = 1;
mdlp->nitems_max = 1;
mdlp->item =
(msgdomain_ty **) xmalloc (mdlp->nitems_max * sizeof (msgdomain_ty *));
mdlp->item[0] = msgdomain_alloc (MESSAGE_DOMAIN_DEFAULT, use_hashtable);
mdlp->use_hashtable = use_hashtable;
mdlp->encoding = NULL;
return mdlp;
}
void
msgdomain_list_free (msgdomain_list_ty *mdlp)
{
size_t j;
for (j = 0; j < mdlp->nitems; ++j)
msgdomain_free (mdlp->item[j]);
if (mdlp->item)
free (mdlp->item);
free (mdlp);
}
void
msgdomain_list_append (msgdomain_list_ty *mdlp, msgdomain_ty *mdp)
{
if (mdlp->nitems >= mdlp->nitems_max)
{
size_t nbytes;
mdlp->nitems_max = mdlp->nitems_max * 2 + 4;
nbytes = mdlp->nitems_max * sizeof (msgdomain_ty *);
mdlp->item = xrealloc (mdlp->item, nbytes);
}
mdlp->item[mdlp->nitems++] = mdp;
}
#if 0
void
msgdomain_list_append_list (msgdomain_list_ty *mdlp, msgdomain_list_ty *mdlp2)
{
size_t j;
for (j = 0; j < mdlp2->nitems; ++j)
msgdomain_list_append (mdlp, mdlp2->item[j]);
}
#endif
message_list_ty *
msgdomain_list_sublist (msgdomain_list_ty *mdlp, const char *domain,
bool create)
{
size_t j;
for (j = 0; j < mdlp->nitems; j++)
if (strcmp (mdlp->item[j]->domain, domain) == 0)
return mdlp->item[j]->messages;
if (create)
{
msgdomain_ty *mdp = msgdomain_alloc (domain, mdlp->use_hashtable);
msgdomain_list_append (mdlp, mdp);
return mdp->messages;
}
else
return NULL;
}
#if 0
message_ty *
msgdomain_list_search (msgdomain_list_ty *mdlp, const char *msgid)
{
size_t j;
for (j = 0; j < mdlp->nitems; ++j)
{
msgdomain_ty *mdp;
message_ty *mp;
mdp = mdlp->item[j];
mp = message_list_search (mdp->messages, msgid);
if (mp)
return mp;
}
return NULL;
}
#endif
#if 0
message_ty *
msgdomain_list_search_fuzzy (msgdomain_list_ty *mdlp, const char *msgid)
{
size_t j;
double best_weight;
message_ty *best_mp;
best_weight = 0.6;
best_mp = NULL;
for (j = 0; j < mdlp->nitems; ++j)
{
msgdomain_ty *mdp;
message_ty *mp;
mdp = mdlp->item[j];
mp = message_list_search_fuzzy_inner (mdp->messages, msgid, &best_weight);
if (mp)
best_mp = mp;
}
return best_mp;
}
#endif