/* xgettext Desktop Entry backend.
Copyright (C) 2014-2015 Free Software Foundation, Inc.
This file was written by Daiki Ueno <ueno@gnu.org>, 2014.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/* Specification. */
#include "x-desktop.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "message.h"
#include "xgettext.h"
#include "error.h"
#include "error-progname.h"
#include "xalloc.h"
#include "xvasprintf.h"
#include "hash.h"
#include "gettext.h"
#include "read-desktop.h"
#include "po-charset.h"
#include "c-ctype.h"
#define _(s) gettext(s)
#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
/* ====================== Keyword set customization. ====================== */
/* The syntax of a Desktop Entry file is defined at
http://standards.freedesktop.org/desktop-entry-spec/latest/index.html
Basically, values with 'localestring' type can be translated.
The type of a value is determined by looking at the key associated
with it. The list of available keys are listed on:
http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s05.html */
static hash_table keywords;
static bool default_keywords = true;
static void
add_keyword (const char *name, hash_table *keywords, bool is_list)
{
if (name == NULL)
default_keywords = false;
else
{
if (keywords->table == NULL)
hash_init (keywords, 100);
desktop_add_keyword (keywords, name, is_list);
}
}
void
x_desktop_keyword (const char *name)
{
add_keyword (name, &keywords, false);
}
static void
init_keywords (void)
{
if (default_keywords)
{
if (keywords.table == NULL)
hash_init (&keywords, 100);
desktop_add_default_keywords (&keywords);
default_keywords = false;
}
}
typedef struct extract_desktop_reader_ty extract_desktop_reader_ty;
struct extract_desktop_reader_ty
{
DESKTOP_READER_TY
message_list_ty *mlp;
};
static void
extract_desktop_handle_group (struct desktop_reader_ty *reader,
const char *group)
{
savable_comment_reset ();
}
static void
extract_desktop_handle_pair (struct desktop_reader_ty *reader,
lex_pos_ty *key_pos,
const char *key,
const char *locale,
const char *value)
{
extract_desktop_reader_ty *extract_reader =
(extract_desktop_reader_ty *) reader;
void *keyword_value;
if (!locale /* Skip already translated entry. */
&& hash_find_entry (&keywords, key, strlen (key), &keyword_value) == 0)
{
bool is_list = (bool) keyword_value;
remember_a_message (extract_reader->mlp, NULL,
desktop_unescape_string (value, is_list),
null_context, key_pos,
NULL, savable_comment);
}
savable_comment_reset ();
}
static void
extract_desktop_handle_comment (struct desktop_reader_ty *reader,
const char *buffer)
{
size_t buflen = strlen (buffer);
size_t bufpos = 0;
while (bufpos < buflen
&& c_isspace (buffer[bufpos]))
++bufpos;
while (buflen >= bufpos
&& c_isspace (buffer[buflen - 1]))
--buflen;
if (bufpos < buflen)
{
char *comment = xstrdup (buffer);
comment[buflen] = 0;
savable_comment_add (&comment[bufpos]);
free (comment);
}
}
static void
extract_desktop_handle_blank (struct desktop_reader_ty *reader,
const char *s)
{
savable_comment_reset ();
}
desktop_reader_class_ty extract_methods =
{
sizeof (extract_desktop_reader_ty),
NULL,
NULL,
extract_desktop_handle_group,
extract_desktop_handle_pair,
extract_desktop_handle_comment,
extract_desktop_handle_blank
};
void
extract_desktop (FILE *f,
const char *real_filename, const char *logical_filename,
flag_context_list_table_ty *flag_table,
msgdomain_list_ty *mdlp)
{
desktop_reader_ty *reader = desktop_reader_alloc (&extract_methods);
extract_desktop_reader_ty *extract_reader =
(extract_desktop_reader_ty *) reader;
init_keywords ();
xgettext_current_source_encoding = po_charset_utf8;
extract_reader->mlp = mdlp->item[0]->messages;
desktop_parse (reader, f, real_filename, logical_filename);
desktop_reader_free (reader);
reader = NULL;
}