#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "gettext-po.h"
#include <stdio.h>
#include <stdlib.h>
#include "message.h"
#include "xalloc.h"
#include "read-po.h"
struct po_file
{
msgdomain_list_ty *mdlp;
const char *real_filename;
const char *logical_filename;
const char **domains;
};
struct po_message_iterator
{
message_list_ty *mlp;
size_t index;
};
po_file_t
po_file_read (const char *filename)
{
FILE *fp;
po_file_t file;
fp = fopen (filename, "r");
if (fp == NULL)
return NULL;
file = (struct po_file *) xmalloc (sizeof (struct po_file));
file->real_filename = filename;
file->logical_filename = filename;
file->mdlp = read_po (fp, file->real_filename, file->logical_filename);
file->domains = NULL;
fclose (fp);
return file;
}
void
po_file_free (po_file_t file)
{
msgdomain_list_free (file->mdlp);
if (file->domains != NULL)
free (file->domains);
free (file);
}
const char * const *
po_file_domains (po_file_t file)
{
if (file->domains == NULL)
{
size_t n = file->mdlp->nitems;
const char **domains =
(const char **) xmalloc ((n + 1) * sizeof (const char *));
size_t j;
for (j = 0; j < n; j++)
domains[j] = file->mdlp->item[j]->domain;
domains[n] = NULL;
file->domains = domains;
}
return file->domains;
}
const char *
po_file_domain_header (po_file_t file, const char *domain)
{
message_list_ty *mlp;
size_t j;
if (domain == NULL)
domain = MESSAGE_DOMAIN_DEFAULT;
mlp = msgdomain_list_sublist (file->mdlp, domain, false);
if (mlp != NULL)
for (j = 0; j < mlp->nitems; j++)
if (mlp->item[j]->msgid[0] == '\0' && !mlp->item[j]->obsolete)
{
const char *header = mlp->item[j]->msgstr;
if (header != NULL)
return xstrdup (header);
else
return NULL;
}
return NULL;
}
char *
po_header_field (const char *header, const char *field)
{
size_t len = strlen (field);
const char *line;
for (line = header;;)
{
if (strncmp (line, field, len) == 0
&& line[len] == ':' && line[len + 1] == ' ')
{
const char *value_start;
const char *value_end;
char *value;
value_start = line + len + 2;
value_end = strchr (value_start, '\n');
if (value_end == NULL)
value_end = value_start + strlen (value_start);
value = (char *) xmalloc (value_end - value_start + 1);
memcpy (value, value_start, value_end - value_start);
value[value_end - value_start] = '\0';
return value;
}
line = strchr (line, '\n');
if (line != NULL)
line++;
else
break;
}
return NULL;
}
po_message_iterator_t
po_message_iterator (po_file_t file, const char *domain)
{
po_message_iterator_t iterator;
if (domain == NULL)
domain = MESSAGE_DOMAIN_DEFAULT;
iterator =
(struct po_message_iterator *)
xmalloc (sizeof (struct po_message_iterator));
iterator->mlp = msgdomain_list_sublist (file->mdlp, domain, false);
iterator->index = 0;
return iterator;
}
void
po_message_iterator_free (po_message_iterator_t iterator)
{
free (iterator);
}
po_message_t
po_next_message (po_message_iterator_t iterator)
{
if (iterator->index < iterator->mlp->nitems)
return (po_message_t) iterator->mlp->item[iterator->index++];
else
return NULL;
}
const char *
po_message_msgid (po_message_t message)
{
message_ty *mp = (message_ty *) message;
return mp->msgid;
}
const char *
po_message_msgid_plural (po_message_t message)
{
message_ty *mp = (message_ty *) message;
return mp->msgid_plural;
}
const char *
po_message_msgstr (po_message_t message)
{
message_ty *mp = (message_ty *) message;
return mp->msgstr;
}
const char *
po_message_msgstr_plural (po_message_t message, int index)
{
message_ty *mp = (message_ty *) message;
if (mp->msgid_plural != NULL && index >= 0)
{
const char *p;
const char *p_end = mp->msgstr + mp->msgstr_len;
for (p = mp->msgstr; ; p += strlen (p) + 1, index--)
{
if (p >= p_end)
return NULL;
if (index == 0)
break;
}
return p;
}
else
return NULL;
}
int
po_message_is_obsolete (po_message_t message)
{
message_ty *mp = (message_ty *) message;
return (mp->obsolete ? 1 : 0);
}
int
po_message_is_fuzzy (po_message_t message)
{
message_ty *mp = (message_ty *) message;
return (mp->is_fuzzy ? 1 : 0);
}
int
po_message_is_format (po_message_t message, const char *format_type)
{
message_ty *mp = (message_ty *) message;
size_t len = strlen (format_type);
size_t i;
if (len >= 7 && memcmp (format_type + len - 7, "-format", 7) == 0)
for (i = 0; i < NFORMATS; i++)
if (strlen (format_language[i]) == len - 7
&& memcmp (format_language[i], format_type, len - 7) == 0)
return (possible_format_p (mp->is_format[i]) ? 1 : 0);
return 0;
}