Formatting
This commit is contained in:
parent
f9c308765f
commit
10240c716a
|
@ -11,5 +11,5 @@
|
||||||
#cmakedefine WITH_GTK
|
#cmakedefine WITH_GTK
|
||||||
#cmakedefine HAVE_RESIZETERM
|
#cmakedefine HAVE_RESIZETERM
|
||||||
|
|
||||||
#endif /* ! CONFIG_H */
|
#endif // ! CONFIG_H
|
||||||
|
|
||||||
|
|
|
@ -40,43 +40,43 @@ typedef struct worker_data WorkerData;
|
||||||
|
|
||||||
struct worker_data
|
struct worker_data
|
||||||
{
|
{
|
||||||
gchar **cmdline; //! eSpeak command line
|
gchar **cmdline; ///< eSpeak command line
|
||||||
guint ignore_acronyms : 1; //! Don't spell out acronyms
|
guint ignore_acronyms : 1; ///< Don't spell out acronyms
|
||||||
GRegex *re_stop; //! Regex for stop sequences
|
GRegex *re_stop; ///< Regex for stop sequences
|
||||||
GRegex *re_acronym; //! Regex for ACRONYMS
|
GRegex *re_acronym; ///< Regex for ACRONYMS
|
||||||
|
|
||||||
guint32 start_entry; //! The first entry to be processed
|
guint32 start_entry; ///< The first entry to be processed
|
||||||
guint32 end_entry; //! Past the last entry to be processed
|
guint32 end_entry; ///< Past the last entry to be processed
|
||||||
|
|
||||||
/* Reader, writer */
|
// Reader, writer
|
||||||
GMutex *dict_mutex; //! Locks the dictionary object
|
GMutex *dict_mutex; ///< Locks the dictionary object
|
||||||
|
|
||||||
/* Reader */
|
// Reader
|
||||||
GThread *main_thread; //! A handle to the reader thread
|
GThread *main_thread; ///< A handle to the reader thread
|
||||||
StardictDict *dict; //! The dictionary object
|
StardictDict *dict; ///< The dictionary object
|
||||||
gpointer output; //! Linked-list of pronunciation data
|
gpointer output; ///< Linked-list of pronunciation data
|
||||||
|
|
||||||
GMutex *remaining_mutex; //! Locks the progress stats
|
GMutex *remaining_mutex; ///< Locks the progress stats
|
||||||
GCond *remaining_cond; //! Signals a change in progress
|
GCond *remaining_cond; ///< Signals a change in progress
|
||||||
guint32 remaining; //! How many entries remain
|
guint32 remaining; ///< How many entries remain
|
||||||
guint32 total; //! Total number of entries
|
guint32 total; ///< Total number of entries
|
||||||
|
|
||||||
/* Writer */
|
// Writer
|
||||||
StardictIterator *iterator; //! Iterates over the dictionary
|
StardictIterator *iterator; ///< Iterates over the dictionary
|
||||||
FILE *child_stdin; //! Standard input of eSpeak
|
FILE *child_stdin; ///< Standard input of eSpeak
|
||||||
};
|
};
|
||||||
|
|
||||||
/** eSpeak splits the output on certain characters. */
|
/// eSpeak splits the output on certain characters.
|
||||||
#define LINE_SPLITTING_CHARS ".,:;?!"
|
#define LINE_SPLITTING_CHARS ".,:;?!"
|
||||||
|
|
||||||
/** We don't want to include brackets either. */
|
/// We don't want to include brackets either.
|
||||||
#define OTHER_STOP_CHARS "([{<"
|
#define OTHER_STOP_CHARS "([{<"
|
||||||
|
|
||||||
/** A void word used to make a unique "no pronunciation available" mark. */
|
/// A void word used to make a unique "no pronunciation available" mark.
|
||||||
#define VOID_ENTRY "not present in any dictionary"
|
#define VOID_ENTRY "not present in any dictionary"
|
||||||
|
|
||||||
|
|
||||||
/** Adds dots between characters. */
|
/// Adds dots between characters.
|
||||||
static gboolean
|
static gboolean
|
||||||
writer_acronym_cb (const GMatchInfo *info, GString *res,
|
writer_acronym_cb (const GMatchInfo *info, GString *res,
|
||||||
G_GNUC_UNUSED gpointer data)
|
G_GNUC_UNUSED gpointer data)
|
||||||
|
@ -99,7 +99,7 @@ writer_acronym_cb (const GMatchInfo *info, GString *res,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Writes to espeak's stdin. */
|
/// Writes to espeak's stdin.
|
||||||
static gpointer
|
static gpointer
|
||||||
worker_writer (WorkerData *data)
|
worker_writer (WorkerData *data)
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ worker_writer (WorkerData *data)
|
||||||
word += strspn (word, LINE_SPLITTING_CHARS " \t");
|
word += strspn (word, LINE_SPLITTING_CHARS " \t");
|
||||||
gchar *x = g_strdup (word);
|
gchar *x = g_strdup (word);
|
||||||
|
|
||||||
/* Cut the word if needed be */
|
// Cut the word if needed be
|
||||||
error = NULL;
|
error = NULL;
|
||||||
if (g_regex_match_full (data->re_stop,
|
if (g_regex_match_full (data->re_stop,
|
||||||
x, -1, 0, 0, &match_info, &error))
|
x, -1, 0, 0, &match_info, &error))
|
||||||
|
@ -125,7 +125,7 @@ worker_writer (WorkerData *data)
|
||||||
}
|
}
|
||||||
g_match_info_free (match_info);
|
g_match_info_free (match_info);
|
||||||
|
|
||||||
/* Change acronyms so that they're not pronounced as words */
|
// Change acronyms so that they're not pronounced as words
|
||||||
if (!error && !data->ignore_acronyms)
|
if (!error && !data->ignore_acronyms)
|
||||||
{
|
{
|
||||||
char *tmp = g_regex_replace_eval (data->re_acronym,
|
char *tmp = g_regex_replace_eval (data->re_acronym,
|
||||||
|
@ -142,7 +142,7 @@ worker_writer (WorkerData *data)
|
||||||
*x = 0;
|
*x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We might have accidentally cut off everything */
|
// We might have accidentally cut off everything
|
||||||
if (!*x)
|
if (!*x)
|
||||||
{
|
{
|
||||||
g_free (x);
|
g_free (x);
|
||||||
|
@ -160,7 +160,7 @@ worker_writer (WorkerData *data)
|
||||||
return GINT_TO_POINTER (fclose (data->child_stdin));
|
return GINT_TO_POINTER (fclose (data->child_stdin));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the void entry (and test if espeak works). */
|
/// Get the void entry (and test if espeak works).
|
||||||
static gchar *
|
static gchar *
|
||||||
get_void_entry (gchar *cmdline[])
|
get_void_entry (gchar *cmdline[])
|
||||||
{
|
{
|
||||||
|
@ -185,11 +185,11 @@ get_void_entry (gchar *cmdline[])
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads from espeak's stdout. */
|
/// Reads from espeak's stdout.
|
||||||
static gpointer
|
static gpointer
|
||||||
worker (WorkerData *data)
|
worker (WorkerData *data)
|
||||||
{
|
{
|
||||||
/* Spawn eSpeak */
|
// Spawn eSpeak
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gint child_in, child_out;
|
gint child_in, child_out;
|
||||||
if (!g_spawn_async_with_pipes (NULL, data->cmdline, NULL,
|
if (!g_spawn_async_with_pipes (NULL, data->cmdline, NULL,
|
||||||
|
@ -205,7 +205,7 @@ worker (WorkerData *data)
|
||||||
if (!child_stdout)
|
if (!child_stdout)
|
||||||
perror ("fdopen");
|
perror ("fdopen");
|
||||||
|
|
||||||
/* Spawn a writer thread */
|
// Spawn a writer thread
|
||||||
g_mutex_lock (data->dict_mutex);
|
g_mutex_lock (data->dict_mutex);
|
||||||
data->iterator = stardict_iterator_new (data->dict, data->start_entry);
|
data->iterator = stardict_iterator_new (data->dict, data->start_entry);
|
||||||
g_mutex_unlock (data->dict_mutex);
|
g_mutex_unlock (data->dict_mutex);
|
||||||
|
@ -213,7 +213,7 @@ worker (WorkerData *data)
|
||||||
GThread *writer = g_thread_new ("write worker",
|
GThread *writer = g_thread_new ("write worker",
|
||||||
(GThreadFunc) worker_writer, data);
|
(GThreadFunc) worker_writer, data);
|
||||||
|
|
||||||
/* Read the output */
|
// Read the output
|
||||||
g_mutex_lock (data->remaining_mutex);
|
g_mutex_lock (data->remaining_mutex);
|
||||||
guint32 remaining = data->remaining;
|
guint32 remaining = data->remaining;
|
||||||
g_mutex_unlock (data->remaining_mutex);
|
g_mutex_unlock (data->remaining_mutex);
|
||||||
|
@ -236,8 +236,8 @@ worker (WorkerData *data)
|
||||||
*output_end = translation;
|
*output_end = translation;
|
||||||
output_end = (gpointer *) translation;
|
output_end = (gpointer *) translation;
|
||||||
|
|
||||||
/* We limit progress reporting so that
|
// We limit progress reporting so that
|
||||||
* the mutex doesn't spin like crazy */
|
// the mutex doesn't spin like crazy
|
||||||
if ((--remaining & 255) != 0)
|
if ((--remaining & 255) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ worker (WorkerData *data)
|
||||||
|
|
||||||
// --- Main --------------------------------------------------------------------
|
// --- Main --------------------------------------------------------------------
|
||||||
|
|
||||||
/** Copy the contents of one StardictInfo object into another. Ignores path. */
|
/// Copy the contents of one StardictInfo object into another. Ignores path.
|
||||||
static void
|
static void
|
||||||
stardict_info_copy (StardictInfo *dest, const StardictInfo *src)
|
stardict_info_copy (StardictInfo *dest, const StardictInfo *src)
|
||||||
{
|
{
|
||||||
|
@ -284,7 +284,7 @@ stardict_info_copy (StardictInfo *dest, const StardictInfo *src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a list of data fields back to a dictionary. */
|
/// Write a list of data fields back to a dictionary.
|
||||||
static gboolean
|
static gboolean
|
||||||
write_fields (Generator *generator, GList *fields, gboolean sts, GError **error)
|
write_fields (Generator *generator, GList *fields, gboolean sts, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -356,7 +356,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
g_option_context_free (ctx);
|
g_option_context_free (ctx);
|
||||||
|
|
||||||
/* See if we can run espeak */
|
// See if we can run espeak
|
||||||
static gchar *cmdline[] = { "espeak", "--ipa", "-q", NULL, NULL, NULL };
|
static gchar *cmdline[] = { "espeak", "--ipa", "-q", NULL, NULL, NULL };
|
||||||
|
|
||||||
if (voice)
|
if (voice)
|
||||||
|
@ -367,7 +367,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
gchar *void_entry = g_strstrip (get_void_entry (cmdline));
|
gchar *void_entry = g_strstrip (get_void_entry (cmdline));
|
||||||
|
|
||||||
/* Load the dictionary */
|
// Load the dictionary
|
||||||
printf ("Loading the original dictionary...\n");
|
printf ("Loading the original dictionary...\n");
|
||||||
StardictDict *dict = stardict_dict_new (argv[1], &error);
|
StardictDict *dict = stardict_dict_new (argv[1], &error);
|
||||||
if (!dict)
|
if (!dict)
|
||||||
|
@ -395,7 +395,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
n_processes);
|
n_processes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spawn worker threads to generate pronunciation data */
|
// Spawn worker threads to generate pronunciation data
|
||||||
static GMutex dict_mutex;
|
static GMutex dict_mutex;
|
||||||
|
|
||||||
static GMutex remaining_mutex;
|
static GMutex remaining_mutex;
|
||||||
|
@ -434,7 +434,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
g_thread_new ("worker", (GThreadFunc) worker, &data[i]);
|
g_thread_new ("worker", (GThreadFunc) worker, &data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop while the threads still have some work to do and report status */
|
// Loop while the threads still have some work to do and report status
|
||||||
g_mutex_lock (&remaining_mutex);
|
g_mutex_lock (&remaining_mutex);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -460,7 +460,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
g_regex_unref (re_stop);
|
g_regex_unref (re_stop);
|
||||||
g_regex_unref (re_acronym);
|
g_regex_unref (re_acronym);
|
||||||
|
|
||||||
/* Put extended entries into a new dictionary */
|
// Put extended entries into a new dictionary
|
||||||
Generator *generator = generator_new (argv[2], &error);
|
Generator *generator = generator_new (argv[2], &error);
|
||||||
if (!generator)
|
if (!generator)
|
||||||
{
|
{
|
||||||
|
@ -472,7 +472,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
StardictInfo *info = generator->info;
|
StardictInfo *info = generator->info;
|
||||||
stardict_info_copy (info, stardict_dict_get_info (dict));
|
stardict_info_copy (info, stardict_dict_get_info (dict));
|
||||||
|
|
||||||
/* This gets incremented each time an entry is finished */
|
// This gets incremented each time an entry is finished
|
||||||
info->word_count = 0;
|
info->word_count = 0;
|
||||||
|
|
||||||
if (info->same_type_sequence)
|
if (info->same_type_sequence)
|
||||||
|
@ -482,7 +482,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
info->same_type_sequence = new_sts;
|
info->same_type_sequence = new_sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out all the entries together with the pronunciation */
|
// Write out all the entries together with the pronunciation
|
||||||
for (i = 0; i < n_processes; i++)
|
for (i = 0; i < n_processes; i++)
|
||||||
{
|
{
|
||||||
StardictIterator *iterator =
|
StardictIterator *iterator =
|
||||||
|
@ -508,8 +508,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
// g_printerr ("%s /%s/\n",
|
// g_printerr ("%s /%s/\n",
|
||||||
// stardict_iterator_get_word (iterator), pronunciation);
|
// stardict_iterator_get_word (iterator), pronunciation);
|
||||||
|
|
||||||
/* For the sake of simplicity we fake a new start;
|
// For the sake of simplicity we fake a new start;
|
||||||
* write_fields() only iterates the list in one direction. */
|
// write_fields() only iterates the list in one direction.
|
||||||
StardictEntryField field;
|
StardictEntryField field;
|
||||||
field.type = 't';
|
field.type = 't';
|
||||||
field.data = pronunciation;
|
field.data = pronunciation;
|
||||||
|
|
|
@ -50,7 +50,7 @@ free_gzip_header (gz_header *gzh)
|
||||||
g_free (gzh->name); gzh->name = NULL;
|
g_free (gzh->name); gzh->name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reading the header in manually due to stupidity of the ZLIB API. */
|
// Reading the header in manually due to stupidity of the ZLIB API.
|
||||||
static gboolean
|
static gboolean
|
||||||
read_gzip_header (GInputStream *is, gz_header *gzh,
|
read_gzip_header (GInputStream *is, gz_header *gzh,
|
||||||
goffset *first_block_offset, GError **error)
|
goffset *first_block_offset, GError **error)
|
||||||
|
@ -279,19 +279,19 @@ static gssize dictzip_input_stream_skip (GInputStream *stream, gsize count,
|
||||||
|
|
||||||
struct dictzip_input_stream_private
|
struct dictzip_input_stream_private
|
||||||
{
|
{
|
||||||
GFileInfo * file_info; //!< File information from gzip header
|
GFileInfo * file_info; ///< File information from gzip header
|
||||||
|
|
||||||
goffset first_block_offset; //!< Offset to the first block/chunk
|
goffset first_block_offset; ///< Offset to the first block/chunk
|
||||||
gsize chunk_length; //!< Uncompressed chunk length
|
gsize chunk_length; ///< Uncompressed chunk length
|
||||||
gsize n_chunks; //!< Number of chunks in file
|
gsize n_chunks; ///< Number of chunks in file
|
||||||
guint16 * chunks; //!< Chunk sizes after compression
|
guint16 * chunks; ///< Chunk sizes after compression
|
||||||
|
|
||||||
z_stream zs; //!< zlib decompression context
|
z_stream zs; ///< zlib decompression context
|
||||||
gpointer input_buffer; //!< Input buffer
|
gpointer input_buffer; ///< Input buffer
|
||||||
|
|
||||||
goffset offset; //!< Current offset
|
goffset offset; ///< Current offset
|
||||||
gpointer * decompressed; //!< Array of decompressed chunks
|
gpointer * decompressed; ///< Array of decompressed chunks
|
||||||
gsize last_chunk_length; //!< Size of the last chunk
|
gsize last_chunk_length; ///< Size of the last chunk
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_EXTENDED (DictzipInputStream, dictzip_input_stream,
|
G_DEFINE_TYPE_EXTENDED (DictzipInputStream, dictzip_input_stream,
|
||||||
|
@ -422,7 +422,7 @@ get_chunk (DictzipInputStream *self, guint chunk_id, GError **error)
|
||||||
gpointer chunk = priv->decompressed[chunk_id];
|
gpointer chunk = priv->decompressed[chunk_id];
|
||||||
if (!chunk)
|
if (!chunk)
|
||||||
{
|
{
|
||||||
/* Just inflating the file piece by piece as needed. */
|
// Just inflating the file piece by piece as needed.
|
||||||
gsize chunk_size;
|
gsize chunk_size;
|
||||||
chunk = inflate_chunk (self, chunk_id, &chunk_size, error);
|
chunk = inflate_chunk (self, chunk_id, &chunk_size, error);
|
||||||
if (!chunk)
|
if (!chunk)
|
||||||
|
@ -452,8 +452,8 @@ dictzip_input_stream_seek (GSeekable *seekable, goffset offset,
|
||||||
|
|
||||||
if (type == G_SEEK_END)
|
if (type == G_SEEK_END)
|
||||||
{
|
{
|
||||||
/* This could be implemented by retrieving the last chunk
|
// This could be implemented by retrieving the last chunk
|
||||||
* and deducing the filesize, should the functionality be needed. */
|
// and deducing the filesize, should the functionality be needed.
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
"I don't know where the stream ends, cannot seek there");
|
"I don't know where the stream ends, cannot seek there");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -541,7 +541,7 @@ dictzip_input_stream_skip (GInputStream *stream, gsize count,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create an input stream for the underlying dictzip file. */
|
/// Create an input stream for the underlying dictzip file.
|
||||||
DictzipInputStream *
|
DictzipInputStream *
|
||||||
dictzip_input_stream_new (GInputStream *base_stream, GError **error)
|
dictzip_input_stream_new (GInputStream *base_stream, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -560,7 +560,7 @@ dictzip_input_stream_new (GInputStream *base_stream, GError **error)
|
||||||
"base-stream", base_stream, "close-base-stream", FALSE, NULL);
|
"base-stream", base_stream, "close-base-stream", FALSE, NULL);
|
||||||
DictzipInputStreamPrivate *priv = self->priv;
|
DictzipInputStreamPrivate *priv = self->priv;
|
||||||
|
|
||||||
/* Decode the header. */
|
// Decode the header.
|
||||||
gz_header gzh;
|
gz_header gzh;
|
||||||
if (!read_gzip_header (G_INPUT_STREAM (base_stream),
|
if (!read_gzip_header (G_INPUT_STREAM (base_stream),
|
||||||
&gzh, &priv->first_block_offset, &err))
|
&gzh, &priv->first_block_offset, &err))
|
||||||
|
@ -584,7 +584,7 @@ dictzip_input_stream_new (GInputStream *base_stream, GError **error)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store file information. */
|
// Store file information.
|
||||||
priv->file_info = g_file_info_new ();
|
priv->file_info = g_file_info_new ();
|
||||||
|
|
||||||
if (gzh.time != 0)
|
if (gzh.time != 0)
|
||||||
|
@ -596,7 +596,7 @@ dictzip_input_stream_new (GInputStream *base_stream, GError **error)
|
||||||
if (gzh.name && *gzh.name)
|
if (gzh.name && *gzh.name)
|
||||||
g_file_info_set_name (priv->file_info, (gchar *) gzh.name);
|
g_file_info_set_name (priv->file_info, (gchar *) gzh.name);
|
||||||
|
|
||||||
/* Initialise zlib. */
|
// Initialise zlib.
|
||||||
int z_err;
|
int z_err;
|
||||||
z_err = inflateInit2 (&priv->zs, -15);
|
z_err = inflateInit2 (&priv->zs, -15);
|
||||||
if (z_err != Z_OK)
|
if (z_err != Z_OK)
|
||||||
|
@ -608,7 +608,7 @@ dictzip_input_stream_new (GInputStream *base_stream, GError **error)
|
||||||
|
|
||||||
priv->input_buffer = g_malloc (65536);
|
priv->input_buffer = g_malloc (65536);
|
||||||
priv->decompressed = g_new0 (gpointer, priv->n_chunks);
|
priv->decompressed = g_new0 (gpointer, priv->n_chunks);
|
||||||
priv->last_chunk_length = -1; // We don't know yet.
|
priv->last_chunk_length = -1; // We don't know yet.
|
||||||
|
|
||||||
free_gzip_header (&gzh);
|
free_gzip_header (&gzh);
|
||||||
return self;
|
return self;
|
||||||
|
@ -619,7 +619,7 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return file information for the compressed file. */
|
/// Return file information for the compressed file.
|
||||||
GFileInfo *
|
GFileInfo *
|
||||||
dictzip_input_stream_get_file_info (DictzipInputStream *self)
|
dictzip_input_stream_get_file_info (DictzipInputStream *self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,12 +21,12 @@
|
||||||
#ifndef DICTZIP_INPUT_STREAM_H
|
#ifndef DICTZIP_INPUT_STREAM_H
|
||||||
#define DICTZIP_INPUT_STREAM_H
|
#define DICTZIP_INPUT_STREAM_H
|
||||||
|
|
||||||
/** Random-access dictzip reader. */
|
/// Random-access dictzip reader.
|
||||||
typedef struct dictzip_input_stream DictzipInputStream;
|
typedef struct dictzip_input_stream DictzipInputStream;
|
||||||
typedef struct dictzip_input_stream_class DictzipInputStreamClass;
|
typedef struct dictzip_input_stream_class DictzipInputStreamClass;
|
||||||
typedef struct dictzip_input_stream_private DictzipInputStreamPrivate;
|
typedef struct dictzip_input_stream_private DictzipInputStreamPrivate;
|
||||||
|
|
||||||
/* GObject boilerplate. */
|
// GObject boilerplate.
|
||||||
#define DICTZIP_TYPE_INPUT_STREAM (dictzip_input_stream_get_type ())
|
#define DICTZIP_TYPE_INPUT_STREAM (dictzip_input_stream_get_type ())
|
||||||
#define DICTZIP_INPUT_STREAM(obj) \
|
#define DICTZIP_INPUT_STREAM(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||||
|
@ -74,4 +74,4 @@ DictzipInputStream *dictzip_input_stream_new
|
||||||
GFileInfo *dictzip_input_stream_get_file_info (DictzipInputStream *self);
|
GFileInfo *dictzip_input_stream_get_file_info (DictzipInputStream *self);
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! DICTZIP_INPUT_STREAM_H */
|
#endif // ! DICTZIP_INPUT_STREAM_H
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "generator.h"
|
#include "generator.h"
|
||||||
|
|
||||||
|
|
||||||
/** Creates an output stream for a path plus suffix. */
|
/// Creates an output stream for a path plus suffix.
|
||||||
static GFileOutputStream *
|
static GFileOutputStream *
|
||||||
replace_file_by_suffix (const gchar *base, const gchar *suffix, GError **error)
|
replace_file_by_suffix (const gchar *base, const gchar *suffix, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ replace_file_by_suffix (const gchar *base, const gchar *suffix, GError **error)
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a Stardict dictionary generator for the specified base. */
|
/// Creates a Stardict dictionary generator for the specified basename.
|
||||||
Generator *
|
Generator *
|
||||||
generator_new (const gchar *base, GError **error)
|
generator_new (const gchar *base, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -80,7 +80,7 @@ error_dict:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Finishes the dictionary and writes the .ifo file. */
|
/// Finishes the dictionary and writes the .ifo file.
|
||||||
gboolean
|
gboolean
|
||||||
generator_finish (Generator *self, GError **error)
|
generator_finish (Generator *self, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -132,21 +132,21 @@ generator_finish (Generator *self, GError **error)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Start writing a dictionary entry. */
|
/// Start writing a dictionary entry.
|
||||||
void
|
void
|
||||||
generator_begin_entry (Generator *self)
|
generator_begin_entry (Generator *self)
|
||||||
{
|
{
|
||||||
self->entry_mark = g_seekable_tell (G_SEEKABLE (self->dict_stream));
|
self->entry_mark = g_seekable_tell (G_SEEKABLE (self->dict_stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write the data type of an entry field, when there's no sametypesequence. */
|
/// Write the data type of an entry field, when there's no sametypesequence.
|
||||||
gboolean
|
gboolean
|
||||||
generator_write_type (Generator *self, gchar type, GError **error)
|
generator_write_type (Generator *self, gchar type, GError **error)
|
||||||
{
|
{
|
||||||
return g_data_output_stream_put_byte (self->dict_data, type, NULL, error);
|
return g_data_output_stream_put_byte (self->dict_data, type, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a raw binary field. */
|
/// Write a raw binary field.
|
||||||
gboolean
|
gboolean
|
||||||
generator_write_raw (Generator *self,
|
generator_write_raw (Generator *self,
|
||||||
gpointer data, gsize data_size, gboolean mark_end, GError **error)
|
gpointer data, gsize data_size, gboolean mark_end, GError **error)
|
||||||
|
@ -160,7 +160,7 @@ generator_write_raw (Generator *self,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a text string. */
|
/// Write a text string.
|
||||||
gboolean
|
gboolean
|
||||||
generator_write_string (Generator *self,
|
generator_write_string (Generator *self,
|
||||||
const gchar *s, gboolean mark_end, GError **error)
|
const gchar *s, gboolean mark_end, GError **error)
|
||||||
|
@ -172,7 +172,7 @@ generator_write_string (Generator *self,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Finishes the current entry and writes it into the index. */
|
/// Finishes the current entry and writes it into the index.
|
||||||
gboolean
|
gboolean
|
||||||
generator_finish_entry (Generator *self, const gchar *word, GError **error)
|
generator_finish_entry (Generator *self, const gchar *word, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -189,7 +189,7 @@ generator_finish_entry (Generator *self, const gchar *word, GError **error)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destroys the generator object, freeing up system resources. */
|
/// Destroys the generator object, freeing up system resources.
|
||||||
void
|
void
|
||||||
generator_free (Generator *self)
|
generator_free (Generator *self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,20 +24,20 @@
|
||||||
#ifndef GENERATOR_H
|
#ifndef GENERATOR_H
|
||||||
#define GENERATOR_H
|
#define GENERATOR_H
|
||||||
|
|
||||||
/** Simplifies the task of creating a StarDict dictionary. */
|
/// Simplifies the task of creating a StarDict dictionary.
|
||||||
typedef struct generator Generator;
|
typedef struct generator Generator;
|
||||||
|
|
||||||
struct generator
|
struct generator
|
||||||
{
|
{
|
||||||
StardictInfo * info; //!< Dictionary information, fill it in
|
StardictInfo * info; ///< Dictionary information, fill it in
|
||||||
|
|
||||||
goffset entry_mark; //!< Marks the entry's start offset
|
goffset entry_mark; ///< Marks the entry's start offset
|
||||||
|
|
||||||
GFileOutputStream * dict_stream; //!< Dictionary stream
|
GFileOutputStream * dict_stream; ///< Dictionary stream
|
||||||
GDataOutputStream * dict_data; //!< Dictionary data stream wrapper
|
GDataOutputStream * dict_data; ///< Dictionary data stream wrapper
|
||||||
|
|
||||||
GFileOutputStream * idx_stream; //!< Index file stream
|
GFileOutputStream * idx_stream; ///< Index file stream
|
||||||
GDataOutputStream * idx_data; //!< Index file data stream wrapper
|
GDataOutputStream * idx_data; ///< Index file data stream wrapper
|
||||||
};
|
};
|
||||||
|
|
||||||
Generator *generator_new (const gchar *base, GError **error);
|
Generator *generator_new (const gchar *base, GError **error);
|
||||||
|
@ -53,4 +53,4 @@ gboolean generator_write_string (Generator *self,
|
||||||
gboolean generator_finish_entry (Generator *self,
|
gboolean generator_finish_entry (Generator *self,
|
||||||
const gchar *word, GError **error);
|
const gchar *word, GError **error);
|
||||||
|
|
||||||
#endif /* ! GENERATOR_H */
|
#endif // ! GENERATOR_H
|
||||||
|
|
131
src/sdtui.c
131
src/sdtui.c
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
#define CTRL_KEY(x) ((x) - 'A' + 1)
|
#define CTRL_KEY(x) ((x) - 'A' + 1)
|
||||||
|
|
||||||
#define TOP_BAR_CUTOFF 2 //!< How many lines are reserved on top
|
#define TOP_BAR_CUTOFF 2 ///< How many lines are reserved on top
|
||||||
|
|
||||||
// --- Utilities ---------------------------------------------------------------
|
// --- Utilities ---------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -62,55 +62,55 @@ unichar_width (gunichar ch)
|
||||||
|
|
||||||
// --- Application -------------------------------------------------------------
|
// --- Application -------------------------------------------------------------
|
||||||
|
|
||||||
/** Data relating to one entry within the dictionary. */
|
/// Data relating to one entry within the dictionary.
|
||||||
typedef struct view_entry ViewEntry;
|
typedef struct view_entry ViewEntry;
|
||||||
/** Encloses application data. */
|
/// Encloses application data.
|
||||||
typedef struct application Application;
|
typedef struct application Application;
|
||||||
/** Application options. */
|
/// Application options.
|
||||||
typedef struct app_options AppOptions;
|
typedef struct app_options AppOptions;
|
||||||
|
|
||||||
struct view_entry
|
struct view_entry
|
||||||
{
|
{
|
||||||
gchar * word; //!< Word
|
gchar * word; ///< Word
|
||||||
gchar ** definitions; //!< Word definition entries
|
gchar ** definitions; ///< Word definition entries
|
||||||
gsize definitions_length; //!< Length of the @a definitions array
|
gsize definitions_length; ///< Length of the @a definitions array
|
||||||
};
|
};
|
||||||
|
|
||||||
struct application
|
struct application
|
||||||
{
|
{
|
||||||
GMainLoop * loop; //!< Main loop
|
GMainLoop * loop; ///< Main loop
|
||||||
termo_t * tk; //!< termo handle
|
termo_t * tk; ///< termo handle
|
||||||
guint tk_timer; //!< termo timeout timer
|
guint tk_timer; ///< termo timeout timer
|
||||||
GIConv ucs4_to_locale; //!< UTF-32 -> locale conversion
|
GIConv ucs4_to_locale; ///< UTF-32 -> locale conversion
|
||||||
gboolean locale_is_utf8; //!< The locale is Unicode
|
gboolean locale_is_utf8; ///< The locale is Unicode
|
||||||
|
|
||||||
StardictDict * dict; //!< The current dictionary
|
StardictDict * dict; ///< The current dictionary
|
||||||
guint show_help : 1; //!< Whether help can be shown
|
guint show_help : 1; ///< Whether help can be shown
|
||||||
|
|
||||||
guint32 top_position; //!< Index of the topmost dict. entry
|
guint32 top_position; ///< Index of the topmost dict. entry
|
||||||
guint top_offset; //!< Offset into the top entry
|
guint top_offset; ///< Offset into the top entry
|
||||||
guint selected; //!< Offset to the selected definition
|
guint selected; ///< Offset to the selected definition
|
||||||
GPtrArray * entries; //!< ViewEntry's within the view
|
GPtrArray * entries; ///< ViewEntry's within the view
|
||||||
|
|
||||||
gchar * search_label; //!< Text of the "Search" label
|
gchar * search_label; ///< Text of the "Search" label
|
||||||
GArray * input; //!< The current search input
|
GArray * input; ///< The current search input
|
||||||
guint input_pos; //!< Cursor position within input
|
guint input_pos; ///< Cursor position within input
|
||||||
gboolean input_confirmed; //!< Input has been confirmed
|
gboolean input_confirmed; ///< Input has been confirmed
|
||||||
|
|
||||||
gfloat division; //!< Position of the division column
|
gfloat division; ///< Position of the division column
|
||||||
|
|
||||||
guint selection_timer; //!< Selection watcher timeout timer
|
guint selection_timer; ///< Selection watcher timeout timer
|
||||||
gint selection_interval; //!< Selection watcher timer interval
|
gint selection_interval; ///< Selection watcher timer interval
|
||||||
gchar * selection_contents; //!< Selection contents
|
gchar * selection_contents; ///< Selection contents
|
||||||
};
|
};
|
||||||
|
|
||||||
struct app_options
|
struct app_options
|
||||||
{
|
{
|
||||||
gboolean show_version; //!< Output version information and quit
|
gboolean show_version; ///< Output version information and quit
|
||||||
gint selection_watcher; //!< Interval in milliseconds, or -1
|
gint selection_watcher; ///< Interval in milliseconds, or -1
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Splits the entry and adds it to a pointer array. */
|
/// Splits the entry and adds it to a pointer array.
|
||||||
static void
|
static void
|
||||||
view_entry_split_add (GPtrArray *out, const gchar *text)
|
view_entry_split_add (GPtrArray *out, const gchar *text)
|
||||||
{
|
{
|
||||||
|
@ -121,7 +121,7 @@ view_entry_split_add (GPtrArray *out, const gchar *text)
|
||||||
g_strfreev (tmp);
|
g_strfreev (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decomposes a dictionary entry into the format we want. */
|
/// Decomposes a dictionary entry into the format we want.
|
||||||
static ViewEntry *
|
static ViewEntry *
|
||||||
view_entry_new (StardictIterator *iterator)
|
view_entry_new (StardictIterator *iterator)
|
||||||
{
|
{
|
||||||
|
@ -178,7 +178,7 @@ view_entry_new (StardictIterator *iterator)
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Release resources associated with the view entry. */
|
/// Release resources associated with the view entry.
|
||||||
static void
|
static void
|
||||||
view_entry_free (ViewEntry *ve)
|
view_entry_free (ViewEntry *ve)
|
||||||
{
|
{
|
||||||
|
@ -187,7 +187,7 @@ view_entry_free (ViewEntry *ve)
|
||||||
g_slice_free1 (sizeof *ve, ve);
|
g_slice_free1 (sizeof *ve, ve);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reload view items. */
|
/// Reload view items.
|
||||||
static void
|
static void
|
||||||
app_reload_view (Application *self)
|
app_reload_view (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -219,7 +219,7 @@ rearm_selection_watcher (Application *self)
|
||||||
}
|
}
|
||||||
#endif // WITH_GTK
|
#endif // WITH_GTK
|
||||||
|
|
||||||
/** Initialize the application core. */
|
/// Initialize the application core.
|
||||||
static void
|
static void
|
||||||
app_init (Application *self, AppOptions *options, const gchar *filename)
|
app_init (Application *self, AppOptions *options, const gchar *filename)
|
||||||
{
|
{
|
||||||
|
@ -274,7 +274,7 @@ app_init (Application *self, AppOptions *options, const gchar *filename)
|
||||||
app_reload_view (self);
|
app_reload_view (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free any resources used by the application. */
|
/// Free any resources used by the application.
|
||||||
static void
|
static void
|
||||||
app_destroy (Application *self)
|
app_destroy (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -297,7 +297,7 @@ app_destroy (Application *self)
|
||||||
g_iconv_close (self->ucs4_to_locale);
|
g_iconv_close (self->ucs4_to_locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Run the main event dispatch loop. */
|
/// Run the main event dispatch loop.
|
||||||
static void
|
static void
|
||||||
app_run (Application *self)
|
app_run (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -309,7 +309,7 @@ app_run (Application *self)
|
||||||
#endif // WITH_GTK
|
#endif // WITH_GTK
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Quit the main event dispatch loop. */
|
/// Quit the main event dispatch loop.
|
||||||
static void
|
static void
|
||||||
app_quit (Application *self)
|
app_quit (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -321,7 +321,7 @@ app_quit (Application *self)
|
||||||
#endif // WITH_GTK
|
#endif // WITH_GTK
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns if the Unicode character is representable in the current locale. */
|
/// Returns if the Unicode character is representable in the current locale.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_is_character_in_locale (Application *self, gunichar ch)
|
app_is_character_in_locale (Application *self, gunichar ch)
|
||||||
{
|
{
|
||||||
|
@ -337,12 +337,11 @@ app_is_character_in_locale (Application *self, gunichar ch)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write the given UTF-8 string padded with spaces.
|
/// Write the given UTF-8 string padded with spaces.
|
||||||
* @param[in] n The number of characters to write, or -1 for the whole string.
|
/// @param[in] n The number of characters to write, or -1 for the whole string.
|
||||||
* @param[in] attrs Text attributes for the text, without padding.
|
/// @param[in] attrs Text attributes for the text, without padding.
|
||||||
* To change the attributes of all output, use attrset().
|
/// To change the attributes of all output, use attrset().
|
||||||
* @return The number of characters output.
|
/// @return The number of characters output.
|
||||||
*/
|
|
||||||
static gsize
|
static gsize
|
||||||
app_add_utf8_string (Application *self, const gchar *str, int attrs, int n)
|
app_add_utf8_string (Application *self, const gchar *str, int attrs, int n)
|
||||||
{
|
{
|
||||||
|
@ -412,7 +411,7 @@ app_add_utf8_string (Application *self, const gchar *str, int attrs, int n)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Render the top bar. */
|
/// Render the top bar.
|
||||||
static void
|
static void
|
||||||
app_redraw_top (Application *self)
|
app_redraw_top (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -445,7 +444,7 @@ app_redraw_top (Application *self)
|
||||||
refresh ();
|
refresh ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Computes width for the left column. */
|
/// Computes width for the left column.
|
||||||
static guint
|
static guint
|
||||||
app_get_left_column_width (Application *self)
|
app_get_left_column_width (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -457,7 +456,7 @@ app_get_left_column_width (Application *self)
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Display a message in the view area. */
|
/// Display a message in the view area.
|
||||||
static void
|
static void
|
||||||
app_show_message (Application *self, const gchar *lines[], gsize len)
|
app_show_message (Application *self, const gchar *lines[], gsize len)
|
||||||
{
|
{
|
||||||
|
@ -491,7 +490,7 @@ app_show_message (Application *self, const gchar *lines[], gsize len)
|
||||||
refresh ();
|
refresh ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Show some information about the program. */
|
/// Show some information about the program.
|
||||||
static void
|
static void
|
||||||
app_show_help (Application *self)
|
app_show_help (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -507,7 +506,7 @@ app_show_help (Application *self)
|
||||||
app_show_message (self, lines, G_N_ELEMENTS (lines));
|
app_show_message (self, lines, G_N_ELEMENTS (lines));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Redraw the dictionary view. */
|
/// Redraw the dictionary view.
|
||||||
static void
|
static void
|
||||||
app_redraw_view (Application *self)
|
app_redraw_view (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -549,7 +548,7 @@ done:
|
||||||
refresh ();
|
refresh ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Just prepends a new view entry into the entries array. */
|
/// Just prepends a new view entry into the entries array.
|
||||||
static ViewEntry *
|
static ViewEntry *
|
||||||
prepend_entry (Application *self, guint32 position)
|
prepend_entry (Application *self, guint32 position)
|
||||||
{
|
{
|
||||||
|
@ -563,7 +562,7 @@ prepend_entry (Application *self, guint32 position)
|
||||||
return g_ptr_array_index (self->entries, 0) = ve;
|
return g_ptr_array_index (self->entries, 0) = ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Just appends a new view entry to the entries array. */
|
/// Just appends a new view entry to the entries array.
|
||||||
static ViewEntry *
|
static ViewEntry *
|
||||||
append_entry (Application *self, guint32 position)
|
append_entry (Application *self, guint32 position)
|
||||||
{
|
{
|
||||||
|
@ -579,7 +578,7 @@ append_entry (Application *self, guint32 position)
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Counts the number of definitions available for seeing. */
|
/// Counts the number of definitions available for seeing.
|
||||||
static guint
|
static guint
|
||||||
app_count_view_items (Application *self)
|
app_count_view_items (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -592,7 +591,7 @@ app_count_view_items (Application *self)
|
||||||
return n_definitions;
|
return n_definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Scroll up @a n entries. */
|
/// Scroll up @a n entries.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_scroll_up (Application *self, guint n)
|
app_scroll_up (Application *self, guint n)
|
||||||
{
|
{
|
||||||
|
@ -606,7 +605,7 @@ app_scroll_up (Application *self, guint n)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We've reached the top */
|
// We've reached the top
|
||||||
if (self->top_position == 0)
|
if (self->top_position == 0)
|
||||||
{
|
{
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
|
@ -617,7 +616,7 @@ app_scroll_up (Application *self, guint n)
|
||||||
self->top_offset = ve->definitions_length - 1;
|
self->top_offset = ve->definitions_length - 1;
|
||||||
n_definitions += ve->definitions_length;
|
n_definitions += ve->definitions_length;
|
||||||
|
|
||||||
/* Remove the last entry if not shown */
|
// Remove the last entry if not shown
|
||||||
ViewEntry *last_entry =
|
ViewEntry *last_entry =
|
||||||
g_ptr_array_index (self->entries, self->entries->len - 1);
|
g_ptr_array_index (self->entries, self->entries->len - 1);
|
||||||
if ((gint) (n_definitions - self->top_offset
|
if ((gint) (n_definitions - self->top_offset
|
||||||
|
@ -633,7 +632,7 @@ app_scroll_up (Application *self, guint n)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Scroll down @a n entries. */
|
/// Scroll down @a n entries.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_scroll_down (Application *self, guint n)
|
app_scroll_down (Application *self, guint n)
|
||||||
{
|
{
|
||||||
|
@ -667,7 +666,7 @@ app_scroll_down (Application *self, guint n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix cursor to not point below the view items */
|
// Fix cursor to not point below the view items
|
||||||
if (self->selected >= n_definitions - self->top_offset)
|
if (self->selected >= n_definitions - self->top_offset)
|
||||||
self->selected = n_definitions - self->top_offset - 1;
|
self->selected = n_definitions - self->top_offset - 1;
|
||||||
|
|
||||||
|
@ -675,7 +674,7 @@ app_scroll_down (Application *self, guint n)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Moves the selection one entry up. */
|
/// Moves the selection one entry up.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_one_entry_up (Application *self)
|
app_one_entry_up (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -711,7 +710,7 @@ app_one_entry_up (Application *self)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Moves the selection one entry down. */
|
/// Moves the selection one entry down.
|
||||||
static void
|
static void
|
||||||
app_one_entry_down (Application *self)
|
app_one_entry_down (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -738,7 +737,7 @@ app_one_entry_down (Application *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Redraw everything. */
|
/// Redraw everything.
|
||||||
static void
|
static void
|
||||||
app_redraw (Application *self)
|
app_redraw (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -746,7 +745,7 @@ app_redraw (Application *self)
|
||||||
app_redraw_top (self);
|
app_redraw_top (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Search for the current entry. */
|
/// Search for the current entry.
|
||||||
static void
|
static void
|
||||||
app_search_for_entry (Application *self)
|
app_search_for_entry (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -776,7 +775,7 @@ app_search_for_entry (Application *self)
|
||||||
move (last_y, last_x); \
|
move (last_y, last_x); \
|
||||||
refresh ();
|
refresh ();
|
||||||
|
|
||||||
/** The terminal has been resized, make appropriate changes. */
|
/// The terminal has been resized, make appropriate changes.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_process_resize (Application *self)
|
app_process_resize (Application *self)
|
||||||
{
|
{
|
||||||
|
@ -798,7 +797,7 @@ app_process_resize (Application *self)
|
||||||
|
|
||||||
// --- User input handling -----------------------------------------------------
|
// --- User input handling -----------------------------------------------------
|
||||||
|
|
||||||
/** All the actions that can be performed by the user. */
|
/// All the actions that can be performed by the user.
|
||||||
typedef enum user_action UserAction;
|
typedef enum user_action UserAction;
|
||||||
|
|
||||||
enum user_action
|
enum user_action
|
||||||
|
@ -1160,7 +1159,7 @@ app_process_left_mouse_click (Application *self, int line, int column)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process mouse input. */
|
/// Process mouse input.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_process_mouse (Application *self, termo_key_t *event)
|
app_process_mouse (Application *self, termo_key_t *event)
|
||||||
{
|
{
|
||||||
|
@ -1181,7 +1180,7 @@ app_process_mouse (Application *self, termo_key_t *event)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process input events from the terminal. */
|
/// Process input events from the terminal.
|
||||||
static gboolean
|
static gboolean
|
||||||
app_process_termo_event (Application *self, termo_key_t *event)
|
app_process_termo_event (Application *self, termo_key_t *event)
|
||||||
{
|
{
|
||||||
|
@ -1200,7 +1199,7 @@ app_process_termo_event (Application *self, termo_key_t *event)
|
||||||
|
|
||||||
// --- SIGWINCH ----------------------------------------------------------------
|
// --- SIGWINCH ----------------------------------------------------------------
|
||||||
|
|
||||||
static int g_winch_pipe[2]; /**< SIGWINCH signalling pipe. */
|
static int g_winch_pipe[2]; ///< SIGWINCH signalling pipe.
|
||||||
|
|
||||||
static void
|
static void
|
||||||
winch_handler (int signum)
|
winch_handler (int signum)
|
||||||
|
@ -1456,7 +1455,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
app_redraw (&app);
|
app_redraw (&app);
|
||||||
|
|
||||||
/* Message loop. */
|
// Message loop.
|
||||||
g_io_add_watch (g_io_channel_unix_new (STDIN_FILENO),
|
g_io_add_watch (g_io_channel_unix_new (STDIN_FILENO),
|
||||||
G_IO_IN, process_stdin_input, &app);
|
G_IO_IN, process_stdin_input, &app);
|
||||||
g_io_add_watch (g_io_channel_unix_new (g_winch_pipe[0]),
|
g_io_add_watch (g_io_channel_unix_new (g_winch_pipe[0]),
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
#ifndef STARDICTPRIVATE_H
|
#ifndef STARDICTPRIVATE_H
|
||||||
#define STARDICTPRIVATE_H
|
#define STARDICTPRIVATE_H
|
||||||
|
|
||||||
/** Describes a single entry in the dictionary index. */
|
/// Describes a single entry in the dictionary index.
|
||||||
typedef struct stardict_index_entry StardictIndexEntry;
|
typedef struct stardict_index_entry StardictIndexEntry;
|
||||||
|
|
||||||
/** Describes a single entry in the synonyms index. */
|
/// Describes a single entry in the synonyms index.
|
||||||
typedef struct stardict_synonym_entry StardictSynonymEntry;
|
typedef struct stardict_synonym_entry StardictSynonymEntry;
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,31 +53,31 @@ struct stardict_info
|
||||||
|
|
||||||
struct stardict_index_entry
|
struct stardict_index_entry
|
||||||
{
|
{
|
||||||
gchar * name; //!< The word in utf-8
|
gchar * name; ///< The word in utf-8
|
||||||
guint64 data_offset; //!< Offset of the definition
|
guint64 data_offset; ///< Offset of the definition
|
||||||
guint32 data_size; //!< Size of the definition
|
guint32 data_size; ///< Size of the definition
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stardict_synonym_entry
|
struct stardict_synonym_entry
|
||||||
{
|
{
|
||||||
gchar * word; //!< A synonymous word
|
gchar * word; ///< A synonymous word
|
||||||
guint32 original_word; //!< The original word's index
|
guint32 original_word; ///< The original word's index
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stardict_ifo_key
|
struct stardict_ifo_key
|
||||||
{
|
{
|
||||||
const gchar *name; //!< Name of the key
|
const gchar *name; ///< Name of the key
|
||||||
enum {
|
enum {
|
||||||
IFO_STRING, //!< A @code gchar * @endcode value
|
IFO_STRING, ///< A @code gchar * @endcode value
|
||||||
IFO_NUMBER //!< A @code gulong @endcode value
|
IFO_NUMBER ///< A @code gulong @endcode value
|
||||||
} type; //!< Type of the value
|
} type; ///< Type of the value
|
||||||
size_t offset; //!< Offset within StardictInfo
|
size_t offset; ///< Offset within StardictInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Lists all the entries in StardictInfo. */
|
/// Lists all the entries in StardictInfo.
|
||||||
extern const struct stardict_ifo_key _stardict_ifo_keys[];
|
extern const struct stardict_ifo_key _stardict_ifo_keys[];
|
||||||
|
|
||||||
/** Denotes the length of _stardict_ifo_keys. */
|
/// Denotes the length of _stardict_ifo_keys.
|
||||||
extern gsize _stardict_ifo_keys_length;
|
extern gsize _stardict_ifo_keys_length;
|
||||||
|
|
||||||
#endif /* ! STARDICTPRIVATE_H */
|
#endif // ! STARDICTPRIVATE_H
|
||||||
|
|
115
src/stardict.c
115
src/stardict.c
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
// --- Utilities ---------------------------------------------------------------
|
// --- Utilities ---------------------------------------------------------------
|
||||||
|
|
||||||
/** String compare function used for StarDict indexes. */
|
/// String compare function used for StarDict indexes.
|
||||||
static inline gint
|
static inline gint
|
||||||
stardict_strcmp (const gchar *s1, const gchar *s2)
|
stardict_strcmp (const gchar *s1, const gchar *s2)
|
||||||
{
|
{
|
||||||
|
@ -60,18 +60,18 @@ stardict_error_quark (void)
|
||||||
|
|
||||||
// --- IFO reader --------------------------------------------------------------
|
// --- IFO reader --------------------------------------------------------------
|
||||||
|
|
||||||
/** Helper class for reading .ifo files. */
|
/// Helper class for reading .ifo files.
|
||||||
typedef struct ifo_reader IfoReader;
|
typedef struct ifo_reader IfoReader;
|
||||||
|
|
||||||
struct ifo_reader
|
struct ifo_reader
|
||||||
{
|
{
|
||||||
gchar * data; //!< File data terminated with \0
|
gchar * data; ///< File data terminated with \0
|
||||||
gchar * data_end; //!< Where the final \0 char. is
|
gchar * data_end; ///< Where the final \0 char. is
|
||||||
|
|
||||||
gchar * start; //!< Start of the current token
|
gchar * start; ///< Start of the current token
|
||||||
|
|
||||||
gchar * key; //!< The key (points into @a data)
|
gchar * key; ///< The key (points into @a data)
|
||||||
gchar * value; //!< The value (points into @a data)
|
gchar * value; ///< The value (points into @a data)
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -148,31 +148,30 @@ ifo_reader_read (IfoReader *ir)
|
||||||
|
|
||||||
// --- StardictInfo ------------------------------------------------------------
|
// --- StardictInfo ------------------------------------------------------------
|
||||||
|
|
||||||
/** Return the filesystem path for the dictionary. */
|
/// Return the filesystem path for the dictionary.
|
||||||
const gchar *
|
const gchar *
|
||||||
stardict_info_get_path (StardictInfo *sdi)
|
stardict_info_get_path (StardictInfo *sdi)
|
||||||
{
|
{
|
||||||
return sdi->path;
|
return sdi->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the name of the dictionary. */
|
/// Return the name of the dictionary.
|
||||||
const gchar *
|
const gchar *
|
||||||
stardict_info_get_book_name (StardictInfo *sdi)
|
stardict_info_get_book_name (StardictInfo *sdi)
|
||||||
{
|
{
|
||||||
return sdi->book_name;
|
return sdi->book_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the word count of the dictionary. Note that this information comes
|
/// Return the word count of the dictionary. Note that this information comes
|
||||||
* from the .ifo file, while the dictionary could successfully load with
|
/// from the .ifo file, while the dictionary could successfully load with
|
||||||
* a different count of word entries.
|
/// a different count of word entries.
|
||||||
*/
|
|
||||||
gsize
|
gsize
|
||||||
stardict_info_get_word_count (StardictInfo *sdi)
|
stardict_info_get_word_count (StardictInfo *sdi)
|
||||||
{
|
{
|
||||||
return sdi->word_count;
|
return sdi->word_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destroy the dictionary info object. */
|
/// Destroy the dictionary info object.
|
||||||
void
|
void
|
||||||
stardict_info_free (StardictInfo *sdi)
|
stardict_info_free (StardictInfo *sdi)
|
||||||
{
|
{
|
||||||
|
@ -328,12 +327,11 @@ error:
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** List all dictionary files located in a path.
|
/// List all dictionary files located in a path.
|
||||||
* @return GList<StardictInfo *>. Deallocate the list with:
|
/// @return GList<StardictInfo *>. Deallocate the list with:
|
||||||
* @code
|
/// @code
|
||||||
* g_list_free_full ((GDestroyNotify) stardict_info_free);
|
/// g_list_free_full ((GDestroyNotify) stardict_info_free);
|
||||||
* @endcode
|
/// @endcode
|
||||||
*/
|
|
||||||
GList *
|
GList *
|
||||||
stardict_list_dictionaries (const gchar *path)
|
stardict_list_dictionaries (const gchar *path)
|
||||||
{
|
{
|
||||||
|
@ -369,18 +367,17 @@ struct stardict_dict_private
|
||||||
GArray * index; //!< Word index
|
GArray * index; //!< Word index
|
||||||
GArray * synonyms; //!< Synonyms
|
GArray * synonyms; //!< Synonyms
|
||||||
|
|
||||||
/* The collated indexes are only permutations of their normal selves. */
|
// The collated indexes are only permutations of their normal selves.
|
||||||
|
|
||||||
UCollator * collator; //!< ICU index collator
|
UCollator * collator; //!< ICU index collator
|
||||||
GArray * collated_index; //!< Sorted indexes into @a index
|
GArray * collated_index; //!< Sorted indexes into @a index
|
||||||
GArray * collated_synonyms; //!< Sorted indexes into @a synonyms
|
GArray * collated_synonyms; //!< Sorted indexes into @a synonyms
|
||||||
|
|
||||||
/* There are currently three ways the dictionary data can be read:
|
// There are currently three ways the dictionary data can be read:
|
||||||
* through mmap(), from a seekable GInputStream, or from a preallocated
|
// through mmap(), from a seekable GInputStream, or from a preallocated
|
||||||
* chunk of memory that the whole dictionary has been decompressed into.
|
// chunk of memory that the whole dictionary has been decompressed into.
|
||||||
*
|
//
|
||||||
* It wouldn't be unreasonable to drop the support for regular gzip files.
|
// It wouldn't be unreasonable to drop the support for regular gzip files.
|
||||||
*/
|
|
||||||
|
|
||||||
GInputStream * dict_stream; //!< Dictionary input stream handle
|
GInputStream * dict_stream; //!< Dictionary input stream handle
|
||||||
GMappedFile * mapped_dict; //!< Dictionary memory map handle
|
GMappedFile * mapped_dict; //!< Dictionary memory map handle
|
||||||
|
@ -432,9 +429,8 @@ stardict_dict_init (StardictDict *self)
|
||||||
STARDICT_TYPE_DICT, StardictDictPrivate);
|
STARDICT_TYPE_DICT, StardictDictPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load a StarDict dictionary.
|
/// Load a StarDict dictionary.
|
||||||
* @param[in] filename Path to the .ifo file
|
/// @param[in] filename Path to the .ifo file
|
||||||
*/
|
|
||||||
StardictDict *
|
StardictDict *
|
||||||
stardict_dict_new (const gchar *filename, GError **error)
|
stardict_dict_new (const gchar *filename, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -450,9 +446,8 @@ stardict_dict_new (const gchar *filename, GError **error)
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return information about a loaded dictionary. The returned reference is
|
/// Return information about a loaded dictionary. The returned reference is
|
||||||
* only valid for the lifetime of the dictionary object.
|
/// only valid for the lifetime of the dictionary object.
|
||||||
*/
|
|
||||||
StardictInfo *
|
StardictInfo *
|
||||||
stardict_dict_get_info (StardictDict *sd)
|
stardict_dict_get_info (StardictDict *sd)
|
||||||
{
|
{
|
||||||
|
@ -460,7 +455,7 @@ stardict_dict_get_info (StardictDict *sd)
|
||||||
return sd->priv->info;
|
return sd->priv->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load a StarDict index from a GIO input stream. */
|
/// Load a StarDict index from a GIO input stream.
|
||||||
static gboolean
|
static gboolean
|
||||||
load_idx_internal (StardictDict *sd, GInputStream *is, GError **error)
|
load_idx_internal (StardictDict *sd, GInputStream *is, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -503,7 +498,7 @@ error:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load a StarDict index. */
|
/// Load a StarDict index.
|
||||||
static gboolean
|
static gboolean
|
||||||
load_idx (StardictDict *sd, const gchar *filename,
|
load_idx (StardictDict *sd, const gchar *filename,
|
||||||
gboolean gzipped, GError **error)
|
gboolean gzipped, GError **error)
|
||||||
|
@ -577,7 +572,7 @@ cannot_open:
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destroy an index entry. */
|
/// Destroy an index entry.
|
||||||
static void
|
static void
|
||||||
index_destroy_cb (gpointer sde)
|
index_destroy_cb (gpointer sde)
|
||||||
{
|
{
|
||||||
|
@ -585,7 +580,7 @@ index_destroy_cb (gpointer sde)
|
||||||
g_free (e->name);
|
g_free (e->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destroy a synonym entry. */
|
/// Destroy a synonym entry.
|
||||||
static void
|
static void
|
||||||
syn_destroy_cb (gpointer sde)
|
syn_destroy_cb (gpointer sde)
|
||||||
{
|
{
|
||||||
|
@ -593,7 +588,7 @@ syn_destroy_cb (gpointer sde)
|
||||||
g_free (e->word);
|
g_free (e->word);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load StarDict dictionary data. */
|
/// Load StarDict dictionary data.
|
||||||
static gboolean
|
static gboolean
|
||||||
load_dict (StardictDict *sd, const gchar *filename, gboolean gzipped,
|
load_dict (StardictDict *sd, const gchar *filename, gboolean gzipped,
|
||||||
GError **error)
|
GError **error)
|
||||||
|
@ -667,7 +662,7 @@ cannot_open:
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
/** Compare the two strings by collation rules. */
|
/// Compare the two strings by collation rules.
|
||||||
static inline gint
|
static inline gint
|
||||||
stardict_dict_strcoll (gconstpointer s1, gconstpointer s2, gpointer data)
|
stardict_dict_strcoll (gconstpointer s1, gconstpointer s2, gpointer data)
|
||||||
{
|
{
|
||||||
|
@ -699,7 +694,7 @@ stardict_dict_strcoll (gconstpointer s1, gconstpointer s2, gpointer data)
|
||||||
#endif // U_ICU_VERSION_MAJOR_NUM >= 50
|
#endif // U_ICU_VERSION_MAJOR_NUM >= 50
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stricter stardict_dict_strcoll() used to sort the collated index. */
|
/// Stricter stardict_dict_strcoll() used to sort the collated index.
|
||||||
static inline gint
|
static inline gint
|
||||||
stardict_dict_strcoll_for_sorting
|
stardict_dict_strcoll_for_sorting
|
||||||
(gconstpointer s1, gconstpointer s2, gpointer data)
|
(gconstpointer s1, gconstpointer s2, gpointer data)
|
||||||
|
@ -772,9 +767,8 @@ stardict_dict_set_collation (StardictDict *sd, const gchar *collation)
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
/** Load a StarDict dictionary.
|
/// Load a StarDict dictionary.
|
||||||
* @param[in] sdi Parsed .ifo data. The dictionary assumes ownership.
|
/// @param[in] sdi Parsed .ifo data. The dictionary assumes ownership.
|
||||||
*/
|
|
||||||
StardictDict *
|
StardictDict *
|
||||||
stardict_dict_new_from_info (StardictInfo *sdi, GError **error)
|
stardict_dict_new_from_info (StardictInfo *sdi, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -870,9 +864,8 @@ stardict_dict_cmp_synonym (StardictDict *sd, const gchar *word, gint i)
|
||||||
g_array_index (synonyms, StardictSynonymEntry, i).word);
|
g_array_index (synonyms, StardictSynonymEntry, i).word);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return words for which the argument is a synonym of or NULL
|
/// Return words for which the argument is a synonym of or NULL
|
||||||
* if there are no such words.
|
/// if there are no such words.
|
||||||
*/
|
|
||||||
gchar **
|
gchar **
|
||||||
stardict_dict_get_synonyms (StardictDict *sd, const gchar *word)
|
stardict_dict_get_synonyms (StardictDict *sd, const gchar *word)
|
||||||
{
|
{
|
||||||
|
@ -916,11 +909,10 @@ stardict_dict_cmp_index (StardictDict *sd, const gchar *word, gint i)
|
||||||
g_array_index (index, StardictIndexEntry, i).name);
|
g_array_index (index, StardictIndexEntry, i).name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Search for a word. The search is ASCII-case-insensitive.
|
/// Search for a word. The search is ASCII-case-insensitive.
|
||||||
* @param[in] word The word in utf-8 encoding
|
/// @param[in] word The word in utf-8 encoding
|
||||||
* @param[out] success TRUE if found
|
/// @param[out] success TRUE if found
|
||||||
* @return An iterator object pointing to the word, or where it would be
|
/// @return An iterator object pointing to the word, or where it would be
|
||||||
*/
|
|
||||||
StardictIterator *
|
StardictIterator *
|
||||||
stardict_dict_search (StardictDict *sd, const gchar *word, gboolean *success)
|
stardict_dict_search (StardictDict *sd, const gchar *word, gboolean *success)
|
||||||
{
|
{
|
||||||
|
@ -1053,7 +1045,7 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read entry data from GInputStream. */
|
/// Read entry data from GInputStream.
|
||||||
static gchar *
|
static gchar *
|
||||||
read_entry_data_from_stream
|
read_entry_data_from_stream
|
||||||
(GInputStream *stream, guint32 offset, StardictIndexEntry *sie)
|
(GInputStream *stream, guint32 offset, StardictIndexEntry *sie)
|
||||||
|
@ -1089,7 +1081,7 @@ read_entry_data_from_stream
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the data for the specified offset in the index. Unsafe. */
|
/// Return the data for the specified offset in the index. Unsafe.
|
||||||
static StardictEntry *
|
static StardictEntry *
|
||||||
stardict_dict_get_entry (StardictDict *sd, guint32 offset)
|
stardict_dict_get_entry (StardictDict *sd, guint32 offset)
|
||||||
{
|
{
|
||||||
|
@ -1164,9 +1156,8 @@ stardict_entry_init (G_GNUC_UNUSED StardictEntry *sde)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the entries present within the entry.
|
/// Return the entries present within the entry.
|
||||||
* @return GList<StardictEntryField *>
|
/// @return GList<StardictEntryField *>
|
||||||
*/
|
|
||||||
const GList *
|
const GList *
|
||||||
stardict_entry_get_fields (StardictEntry *sde)
|
stardict_entry_get_fields (StardictEntry *sde)
|
||||||
{
|
{
|
||||||
|
@ -1199,7 +1190,7 @@ stardict_iterator_init (G_GNUC_UNUSED StardictIterator *sd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new iterator for the dictionary with offset @a offset. */
|
/// Create a new iterator for the dictionary with offset @a offset.
|
||||||
StardictIterator *
|
StardictIterator *
|
||||||
stardict_iterator_new (StardictDict *sd, guint32 offset)
|
stardict_iterator_new (StardictDict *sd, guint32 offset)
|
||||||
{
|
{
|
||||||
|
@ -1218,7 +1209,7 @@ stardict_iterator_get_real_offset (StardictIterator *sdi)
|
||||||
(sdi->owner->priv->collated_index, guint32, sdi->offset) : sdi->offset;
|
(sdi->owner->priv->collated_index, guint32, sdi->offset) : sdi->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the word in the index that the iterator points at, or NULL. */
|
/// Return the word in the index that the iterator points at, or NULL.
|
||||||
const gchar *
|
const gchar *
|
||||||
stardict_iterator_get_word (StardictIterator *sdi)
|
stardict_iterator_get_word (StardictIterator *sdi)
|
||||||
{
|
{
|
||||||
|
@ -1229,7 +1220,7 @@ stardict_iterator_get_word (StardictIterator *sdi)
|
||||||
StardictIndexEntry, stardict_iterator_get_real_offset (sdi)).name;
|
StardictIndexEntry, stardict_iterator_get_real_offset (sdi)).name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the dictionary entry that the iterator points at, or NULL. */
|
/// Return the dictionary entry that the iterator points at, or NULL.
|
||||||
StardictEntry *
|
StardictEntry *
|
||||||
stardict_iterator_get_entry (StardictIterator *sdi)
|
stardict_iterator_get_entry (StardictIterator *sdi)
|
||||||
{
|
{
|
||||||
|
@ -1240,7 +1231,7 @@ stardict_iterator_get_entry (StardictIterator *sdi)
|
||||||
stardict_iterator_get_real_offset (sdi));
|
stardict_iterator_get_real_offset (sdi));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return whether the iterator points to a valid index entry. */
|
/// Return whether the iterator points to a valid index entry.
|
||||||
gboolean
|
gboolean
|
||||||
stardict_iterator_is_valid (StardictIterator *sdi)
|
stardict_iterator_is_valid (StardictIterator *sdi)
|
||||||
{
|
{
|
||||||
|
@ -1248,7 +1239,7 @@ stardict_iterator_is_valid (StardictIterator *sdi)
|
||||||
return sdi->offset >= 0 && sdi->offset < sdi->owner->priv->index->len;
|
return sdi->offset >= 0 && sdi->offset < sdi->owner->priv->index->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the offset of the iterator within the dictionary index. */
|
/// Return the offset of the iterator within the dictionary index.
|
||||||
gint64
|
gint64
|
||||||
stardict_iterator_get_offset (StardictIterator *sdi)
|
stardict_iterator_get_offset (StardictIterator *sdi)
|
||||||
{
|
{
|
||||||
|
@ -1256,7 +1247,7 @@ stardict_iterator_get_offset (StardictIterator *sdi)
|
||||||
return sdi->offset;
|
return sdi->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the offset of the iterator. */
|
/// Set the offset of the iterator.
|
||||||
void
|
void
|
||||||
stardict_iterator_set_offset
|
stardict_iterator_set_offset
|
||||||
(StardictIterator *sdi, gint64 offset, gboolean relative)
|
(StardictIterator *sdi, gint64 offset, gboolean relative)
|
||||||
|
|
|
@ -25,26 +25,26 @@
|
||||||
#ifndef STARDICT_H
|
#ifndef STARDICT_H
|
||||||
#define STARDICT_H
|
#define STARDICT_H
|
||||||
|
|
||||||
/** An object intended for interacting with a dictionary. */
|
/// An object intended for interacting with a dictionary.
|
||||||
typedef struct stardict_dict StardictDict;
|
typedef struct stardict_dict StardictDict;
|
||||||
typedef struct stardict_dict_class StardictDictClass;
|
typedef struct stardict_dict_class StardictDictClass;
|
||||||
typedef struct stardict_dict_private StardictDictPrivate;
|
typedef struct stardict_dict_private StardictDictPrivate;
|
||||||
|
|
||||||
/** Overall information about a particular dictionary. */
|
/// Overall information about a particular dictionary.
|
||||||
typedef struct stardict_info StardictInfo;
|
typedef struct stardict_info StardictInfo;
|
||||||
|
|
||||||
/** Handles the task of moving around the dictionary. */
|
/// Handles the task of moving around the dictionary.
|
||||||
typedef struct stardict_iterator StardictIterator;
|
typedef struct stardict_iterator StardictIterator;
|
||||||
typedef struct stardict_iterator_class StardictIteratorClass;
|
typedef struct stardict_iterator_class StardictIteratorClass;
|
||||||
|
|
||||||
/** Contains the decoded data for a single word definition. */
|
/// Contains the decoded data for a single word definition.
|
||||||
typedef struct stardict_entry StardictEntry;
|
typedef struct stardict_entry StardictEntry;
|
||||||
typedef struct stardict_entry_class StardictEntryClass;
|
typedef struct stardict_entry_class StardictEntryClass;
|
||||||
|
|
||||||
/** A single field of a word definition. */
|
/// A single field of a word definition.
|
||||||
typedef struct stardict_entry_field StardictEntryField;
|
typedef struct stardict_entry_field StardictEntryField;
|
||||||
|
|
||||||
/* GObject boilerplate. */
|
// GObject boilerplate.
|
||||||
#define STARDICT_TYPE_DICT (stardict_dict_get_type ())
|
#define STARDICT_TYPE_DICT (stardict_dict_get_type ())
|
||||||
#define STARDICT_DICT(obj) \
|
#define STARDICT_DICT(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||||
|
@ -98,7 +98,7 @@ typedef struct stardict_entry_field StardictEntryField;
|
||||||
|
|
||||||
// --- Errors ------------------------------------------------------------------
|
// --- Errors ------------------------------------------------------------------
|
||||||
|
|
||||||
/** General error type. */
|
/// General error type.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STARDICT_ERROR_FILE_NOT_FOUND, //!< Some file was not found
|
STARDICT_ERROR_FILE_NOT_FOUND, //!< Some file was not found
|
||||||
STARDICT_ERROR_INVALID_DATA //!< Dictionary contains invalid data
|
STARDICT_ERROR_INVALID_DATA //!< Dictionary contains invalid data
|
||||||
|
@ -161,43 +161,43 @@ gint64 stardict_iterator_get_offset (StardictIterator *sdi) G_GNUC_PURE;
|
||||||
void stardict_iterator_set_offset
|
void stardict_iterator_set_offset
|
||||||
(StardictIterator *sdi, gint64 offset, gboolean relative);
|
(StardictIterator *sdi, gint64 offset, gboolean relative);
|
||||||
|
|
||||||
/** Go to the next entry. */
|
/// Go to the next entry.
|
||||||
#define stardict_iterator_next(sdi) \
|
#define stardict_iterator_next(sdi) \
|
||||||
(stardict_iterator_set_offset (sdi, 1, TRUE))
|
(stardict_iterator_set_offset (sdi, 1, TRUE))
|
||||||
|
|
||||||
/** Go to the previous entry. */
|
/// Go to the previous entry.
|
||||||
#define stardict_iterator_prev(sdi) \
|
#define stardict_iterator_prev(sdi) \
|
||||||
(stardict_iterator_set_offset (sdi, -1, TRUE))
|
(stardict_iterator_set_offset (sdi, -1, TRUE))
|
||||||
|
|
||||||
// --- Dictionary entries ------------------------------------------------------
|
// --- Dictionary entries ------------------------------------------------------
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STARDICT_FIELD_MEANING = 'm', //!< Word's purely textual meaning
|
STARDICT_FIELD_MEANING = 'm', ///< Word's purely textual meaning
|
||||||
STARDICT_FIELD_LOCALE = 'l', //!< Locale-dependent meaning
|
STARDICT_FIELD_LOCALE = 'l', ///< Locale-dependent meaning
|
||||||
STARDICT_FIELD_PANGO = 'g', //!< Pango text markup language
|
STARDICT_FIELD_PANGO = 'g', ///< Pango text markup language
|
||||||
STARDICT_FIELD_PHONETIC = 't', //!< English phonetic string
|
STARDICT_FIELD_PHONETIC = 't', ///< English phonetic string
|
||||||
STARDICT_FIELD_XDXF = 'x', //!< xdxf language
|
STARDICT_FIELD_XDXF = 'x', ///< xdxf language
|
||||||
STARDICT_FIELD_YB_KANA = 'y', //!< Chinese YinBiao or Japanese KANA
|
STARDICT_FIELD_YB_KANA = 'y', ///< Chinese YinBiao or Japanese KANA
|
||||||
STARDICT_FIELD_POWERWORD = 'k', //!< KingSoft PowerWord's data
|
STARDICT_FIELD_POWERWORD = 'k', ///< KingSoft PowerWord's data
|
||||||
STARDICT_FIELD_MEDIAWIKI = 'w', //!< MediaWiki markup language
|
STARDICT_FIELD_MEDIAWIKI = 'w', ///< MediaWiki markup language
|
||||||
STARDICT_FIELD_HTML = 'h', //!< HTML codes
|
STARDICT_FIELD_HTML = 'h', ///< HTML codes
|
||||||
STARDICT_FIELD_RESOURCE = 'r', //!< Resource file list
|
STARDICT_FIELD_RESOURCE = 'r', ///< Resource file list
|
||||||
STARDICT_FIELD_WAV = 'W', //!< WAV file
|
STARDICT_FIELD_WAV = 'W', ///< WAV file
|
||||||
STARDICT_FIELD_PICTURE = 'P', //!< Picture file
|
STARDICT_FIELD_PICTURE = 'P', ///< Picture file
|
||||||
STARDICT_FIELD_X = 'X' //!< Reserved, experimental extensions
|
STARDICT_FIELD_X = 'X' ///< Reserved, experimental extensions
|
||||||
} StardictEntryFieldType;
|
} StardictEntryFieldType;
|
||||||
|
|
||||||
struct stardict_entry_field
|
struct stardict_entry_field
|
||||||
{
|
{
|
||||||
gchar type; //!< Type of entry (EntryFieldType)
|
gchar type; ///< Type of entry (EntryFieldType)
|
||||||
gpointer data; //!< Raw data or null-terminated string
|
gpointer data; ///< Raw data or null-terminated string
|
||||||
gsize data_size; //!< Size of data, includding any \0
|
gsize data_size; ///< Size of data, includding any \0
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stardict_entry
|
struct stardict_entry
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
GList * fields; //!< List of StardictEntryField's
|
GList * fields; ///< List of StardictEntryField's
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stardict_entry_class
|
struct stardict_entry_class
|
||||||
|
@ -208,4 +208,4 @@ struct stardict_entry_class
|
||||||
GType stardict_entry_get_type (void);
|
GType stardict_entry_get_type (void);
|
||||||
const GList *stardict_entry_get_fields (StardictEntry *sde) G_GNUC_PURE;
|
const GList *stardict_entry_get_fields (StardictEntry *sde) G_GNUC_PURE;
|
||||||
|
|
||||||
#endif /* ! STARDICT_H */
|
#endif // ! STARDICT_H
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
/** Read the whole stream into a byte array. */
|
/// Read the whole stream into a byte array.
|
||||||
gboolean
|
gboolean
|
||||||
stream_read_all (GByteArray *ba, GInputStream *is, GError **error)
|
stream_read_all (GByteArray *ba, GInputStream *is, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -50,7 +50,7 @@ stream_read_all (GByteArray *ba, GInputStream *is, GError **error)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read a null-terminated string from a data input stream. */
|
/// Read a null-terminated string from a data input stream.
|
||||||
gchar *
|
gchar *
|
||||||
stream_read_string (GDataInputStream *dis, GError **error)
|
stream_read_string (GDataInputStream *dis, GError **error)
|
||||||
{
|
{
|
||||||
|
|
10
src/utils.h
10
src/utils.h
|
@ -21,8 +21,8 @@
|
||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
/** After this statement, the element has been found and its index is stored
|
/// After this statement, the element has been found and its index is stored
|
||||||
* in the variable "imid". */
|
/// in the variable "imid".
|
||||||
#define BINARY_SEARCH_BEGIN(max, compare) \
|
#define BINARY_SEARCH_BEGIN(max, compare) \
|
||||||
gint imin = 0, imax = max, imid; \
|
gint imin = 0, imax = max, imid; \
|
||||||
while (imin <= imax) { \
|
while (imin <= imax) { \
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
else if (cmp < 0) imax = imid - 1; \
|
else if (cmp < 0) imax = imid - 1; \
|
||||||
else {
|
else {
|
||||||
|
|
||||||
/** After this statement, the binary search has failed and "imin" stores
|
/// After this statement, the binary search has failed and "imin" stores
|
||||||
* the position where the element can be inserted. */
|
/// the position where the element can be inserted.
|
||||||
#define BINARY_SEARCH_END \
|
#define BINARY_SEARCH_END \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -43,4 +43,4 @@ gchar *stream_read_string (GDataInputStream *dis, GError **error);
|
||||||
gboolean xstrtoul (unsigned long *out, const char *s, int base);
|
gboolean xstrtoul (unsigned long *out, const char *s, int base);
|
||||||
void update_curses_terminal_size (void);
|
void update_curses_terminal_size (void);
|
||||||
|
|
||||||
#endif /* ! UTILS_H */
|
#endif // ! UTILS_H
|
||||||
|
|
Loading…
Reference in New Issue