read-po-abstract.c [plain text]
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "read-po-abstract.h"
#include <stdlib.h>
#include <string.h>
#include "po-gram.h"
#include "po-hash.h"
#include "read-properties.h"
#include "read-stringtable.h"
#include "xalloc.h"
#include "gettext.h"
static abstract_po_reader_ty *callback_arg;
abstract_po_reader_ty *
po_reader_alloc (abstract_po_reader_class_ty *method_table)
{
abstract_po_reader_ty *pop;
pop = (abstract_po_reader_ty *) xmalloc (method_table->size);
pop->methods = method_table;
if (method_table->constructor)
method_table->constructor (pop);
return pop;
}
void
po_reader_free (abstract_po_reader_ty *pop)
{
if (pop->methods->destructor)
pop->methods->destructor (pop);
free (pop);
}
static inline void
call_parse_brief (abstract_po_reader_ty *pop)
{
if (pop->methods->parse_brief)
pop->methods->parse_brief (pop);
}
static inline void
call_parse_debrief (abstract_po_reader_ty *pop)
{
if (pop->methods->parse_debrief)
pop->methods->parse_debrief (pop);
}
static inline void
call_directive_domain (abstract_po_reader_ty *pop, char *name)
{
if (pop->methods->directive_domain)
pop->methods->directive_domain (pop, name);
}
static inline void
call_directive_message (abstract_po_reader_ty *pop,
char *msgid,
lex_pos_ty *msgid_pos,
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
bool force_fuzzy, bool obsolete)
{
if (pop->methods->directive_message)
pop->methods->directive_message (pop, msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos,
force_fuzzy, obsolete);
}
static inline void
call_comment (abstract_po_reader_ty *pop, const char *s)
{
if (pop->methods->comment != NULL)
pop->methods->comment (pop, s);
}
static inline void
call_comment_dot (abstract_po_reader_ty *pop, const char *s)
{
if (pop->methods->comment_dot != NULL)
pop->methods->comment_dot (pop, s);
}
static inline void
call_comment_filepos (abstract_po_reader_ty *pop, const char *name, size_t line)
{
if (pop->methods->comment_filepos)
pop->methods->comment_filepos (pop, name, line);
}
static inline void
call_comment_special (abstract_po_reader_ty *pop, const char *s)
{
if (pop->methods->comment_special != NULL)
pop->methods->comment_special (pop, s);
}
static inline void
po_scan_start (abstract_po_reader_ty *pop)
{
callback_arg = pop;
call_parse_brief (pop);
}
static inline void
po_scan_end (abstract_po_reader_ty *pop)
{
call_parse_debrief (pop);
callback_arg = NULL;
}
void
po_scan (abstract_po_reader_ty *pop, FILE *fp,
const char *real_filename, const char *logical_filename,
input_syntax_ty syntax)
{
switch (syntax)
{
case syntax_po:
lex_start (fp, real_filename, logical_filename);
po_scan_start (pop);
po_gram_parse ();
po_scan_end (pop);
lex_end ();
break;
case syntax_properties:
po_scan_start (pop);
properties_parse (pop, fp, real_filename, logical_filename);
po_scan_end (pop);
break;
case syntax_stringtable:
po_scan_start (pop);
stringtable_parse (pop, fp, real_filename, logical_filename);
po_scan_end (pop);
break;
default:
abort ();
}
if (error_message_count > 0)
error (EXIT_FAILURE, 0,
ngettext ("found %d fatal error", "found %d fatal errors",
error_message_count),
error_message_count);
error_message_count = 0;
}
void
po_callback_domain (char *name)
{
call_directive_domain (callback_arg, name);
}
void
po_callback_message (char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
bool force_fuzzy, bool obsolete)
{
call_directive_message (callback_arg, msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos,
force_fuzzy, obsolete);
}
void
po_callback_comment (const char *s)
{
call_comment (callback_arg, s);
}
void
po_callback_comment_dot (const char *s)
{
call_comment_dot (callback_arg, s);
}
void
po_callback_comment_filepos (const char *name, size_t line)
{
call_comment_filepos (callback_arg, name, line);
}
void
po_callback_comment_special (const char *s)
{
call_comment_special (callback_arg, s);
}
void
po_parse_comment_special (const char *s,
bool *fuzzyp, enum is_format formatp[NFORMATS],
enum is_wrap *wrapp)
{
size_t i;
*fuzzyp = false;
for (i = 0; i < NFORMATS; i++)
formatp[i] = undecided;
*wrapp = undecided;
while (*s != '\0')
{
const char *t;
while (*s != '\0' && strchr ("\n \t\r\f\v,", *s) != NULL)
s++;
t = s;
while (*s != '\0' && strchr ("\n \t\r\f\v,", *s) == NULL)
s++;
if (s != t)
{
size_t len = s - t;
if (len == 5 && memcmp (t, "fuzzy", 5) == 0)
{
*fuzzyp = true;
continue;
}
if (len >= 7 && memcmp (t + len - 7, "-format", 7) == 0)
{
const char *p;
size_t n;
enum is_format value;
p = t;
n = len - 7;
if (n >= 3 && memcmp (p, "no-", 3) == 0)
{
p += 3;
n -= 3;
value = no;
}
else if (n >= 9 && memcmp (p, "possible-", 9) == 0)
{
p += 9;
n -= 9;
value = possible;
}
else if (n >= 11 && memcmp (p, "impossible-", 11) == 0)
{
p += 11;
n -= 11;
value = impossible;
}
else
value = yes;
for (i = 0; i < NFORMATS; i++)
if (strlen (format_language[i]) == n
&& memcmp (format_language[i], p, n) == 0)
{
formatp[i] = value;
break;
}
if (i < NFORMATS)
continue;
}
if (len == 4 && memcmp (t, "wrap", 4) == 0)
{
*wrapp = yes;
continue;
}
if (len == 7 && memcmp (t, "no-wrap", 7) == 0)
{
*wrapp = no;
continue;
}
}
}
}
void
po_callback_comment_dispatcher (const char *s)
{
if (*s == '.')
po_callback_comment_dot (s + 1);
else if (*s == ':')
{
if (po_parse_comment_filepos (s + 1) == 0)
;
else
po_callback_comment (s + 1);
}
else if (*s == ',' || *s == '!')
{
po_callback_comment_special (s + 1);
}
else
{
if (s[0] == ' ' && (s[1] == 'F' || s[1] == 'f') && s[2] == 'i'
&& s[3] == 'l' && s[4] == 'e' && s[5] == ':'
&& po_parse_comment_filepos (s) == 0)
;
else
po_callback_comment (s);
}
}