mirror of
https://github.com/Dushistov/sdcv.git
synced 2025-12-16 09:51:56 +00:00
Compare commits
36 Commits
sdcv_on_ru
...
v0.5.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cd29823cf | ||
|
|
8f16ceae59 | ||
|
|
d0c0a0837f | ||
|
|
d5698bdf33 | ||
|
|
7518be74f9 | ||
|
|
59a821c8f9 | ||
|
|
c9a55c90bd | ||
|
|
e85927e562 | ||
|
|
586215fda7 | ||
|
|
835dffcaf8 | ||
|
|
af6362f5df | ||
|
|
25dd4c8264 | ||
|
|
98e98d0746 | ||
|
|
3105823e8b | ||
|
|
edf73656aa | ||
|
|
5f0f6e036f | ||
|
|
6c01e22961 | ||
|
|
214fbbf91e | ||
|
|
f510300f59 | ||
|
|
aa42132243 | ||
|
|
4b52181898 | ||
|
|
72a15b70a7 | ||
|
|
4c367fc12c | ||
|
|
b2ced870ab | ||
|
|
b4fc882f25 | ||
|
|
82a06b8e69 | ||
|
|
73d6098010 | ||
|
|
5c1357840c | ||
|
|
1667de0650 | ||
|
|
97b13e6702 | ||
|
|
d9f273b858 | ||
|
|
84367a5744 | ||
|
|
7df514e117 | ||
|
|
a1a614b81f | ||
|
|
913fd0a312 | ||
|
|
2d95bd0b12 |
@@ -22,6 +22,7 @@ matrix:
|
||||
- g++-4.8
|
||||
- cmake
|
||||
- libglib2.0-dev
|
||||
- jq
|
||||
# - env: COMPILER_VERSION=3.5
|
||||
# os: linux
|
||||
# compiler: clang++
|
||||
|
||||
@@ -27,11 +27,15 @@ if (NOT GLIB2_FOUND)
|
||||
"make sure that you install it")
|
||||
endif()
|
||||
|
||||
set(WITH_READLINE True CACHE BOOL "Use readline library")
|
||||
|
||||
if (WITH_READLINE)
|
||||
find_path(READLINE_INCLUDE_DIR readline/readline.h)
|
||||
find_library(READLINE_LIBRARY NAMES readline)
|
||||
if (READLINE_INCLUDE_DIR AND READLINE_LIBRARY)
|
||||
set(WITH_READLINE True)
|
||||
if (NOT (READLINE_INCLUDE_DIR AND READLINE_LIBRARY))
|
||||
set(WITH_READLINE False CACHE FORCE)
|
||||
endif ()
|
||||
endif (WITH_READLINE)
|
||||
|
||||
option(ENABLE_NLS "Enable NLS support" True)
|
||||
|
||||
@@ -84,6 +88,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
|
||||
include_directories(
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${GLIB2_INCLUDE_DIRS}
|
||||
${READLINE_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lib
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
@@ -96,7 +101,7 @@ set(CPACK_PACKAGE_VENDOR "Evgeniy Dushistov <dushistov@mail.ru>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.org")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "5")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "0-beta4")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "2")
|
||||
|
||||
set(sdcv_VERSION
|
||||
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
@@ -139,6 +144,10 @@ if (BUILD_TESTS)
|
||||
|
||||
add_sdcv_shell_test(t_list)
|
||||
add_sdcv_shell_test(t_use)
|
||||
add_sdcv_shell_test(t_only_data_dir)
|
||||
add_sdcv_shell_test(t_synonyms)
|
||||
add_sdcv_shell_test(t_json)
|
||||
add_sdcv_shell_test(t_exact)
|
||||
add_sdcv_shell_test(t_interactive)
|
||||
add_sdcv_shell_test(t_utf8output)
|
||||
add_sdcv_shell_test(t_utf8input)
|
||||
|
||||
134
Cargo.lock
generated
134
Cargo.lock
generated
@@ -1,134 +0,0 @@
|
||||
[root]
|
||||
name = "sdcv"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gettext 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rust-ini 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "encoding"
|
||||
version = "0.2.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-japanese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-korean"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-simpchinese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-singlebyte"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-tradchinese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_index_tests"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gettext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "miniz-sys"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-ini"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "sdcv"
|
||||
version = "0.1.0"
|
||||
authors = ["Evgeniy A. Dushistov <dushistov@mail.ru>"]
|
||||
|
||||
[dependencies]
|
||||
getopts = "0.2"
|
||||
gettext = "0.2.0"
|
||||
rust-ini = "0.9.5"
|
||||
byteorder = "0.5"
|
||||
libc = "0.2.14"
|
||||
flate2 = "0.2"
|
||||
5
LICENSE
5
LICENSE
@@ -2,7 +2,8 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -305,7 +306,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
12
NEWS
12
NEWS
@@ -1,3 +1,15 @@
|
||||
Version 0.5.2
|
||||
Synonyms index support (.syn files) by Peter <craven@gmx.net>
|
||||
Add support of json output by Peter <craven@gmx.net> (--json-output)
|
||||
Add -e for exact searches (no fuzzy matches) by Peter <craven@gmx.net>
|
||||
Fix build with clang 3.4.1
|
||||
fix FSF address in license by Tomáš Čech <sleep_walker@suse.com>
|
||||
|
||||
Version 0.5.1
|
||||
Fix usage of SDCV_PAGER by Anton Yuzhaninov
|
||||
Fix build without readline<
|
||||
specify dictionary order by -u switches or ~/.sdcv_ordering by Cong Gu
|
||||
|
||||
Version 0.5
|
||||
- add option to colorize output
|
||||
- Roman Imankulov's patch to better use of readline
|
||||
|
||||
@@ -25,9 +25,16 @@ See sdcv man page for usage description.
|
||||
If you find bug reports it via email to dushistov at mail dot ru.
|
||||
Be sure to include the word "sdcv" somewhere in the "Subject:" field.
|
||||
|
||||
|
||||
* Notes to developer
|
||||
** make source code release
|
||||
#+BEGIN_SRC sh
|
||||
make package_source
|
||||
#+END_SRC
|
||||
** update translation
|
||||
#+BEGIN_SRC sh
|
||||
cd po
|
||||
xgettext -k_ ../src/*.cpp -o new.pot
|
||||
msgmerge -U sdcv.pot new.pot
|
||||
rm new.pot
|
||||
for i in `ls *.po`; do msgmerge -U $i sdcv.pot; done
|
||||
#+END_SRC
|
||||
|
||||
72
doc/sdcv.1
72
doc/sdcv.1
@@ -9,78 +9,92 @@ sdcv \- console version of StarDict program
|
||||
[list of words]
|
||||
.SH DESCRIPTION
|
||||
.I sdcv
|
||||
is simple, cross-platform text-base utility
|
||||
for work with dictionaries in StarDict's format.
|
||||
The word from "list of words" may be string
|
||||
with leading '/' for using Fuzzy search algorithm,
|
||||
with leading '|' for using full-text search,
|
||||
string may contain '?' and '*' for using regexp search.
|
||||
It work in interactive and not interactive mode.
|
||||
is a simple, cross-platform text-based utility
|
||||
for working with dictionaries in StarDict format.
|
||||
Each word from "list of words" may be a string
|
||||
with a leading '/' for using a Fuzzy search algorithm,
|
||||
with a leading '|' for using full-text search,
|
||||
and the string may contain '?' and '*' for regexp search.
|
||||
It works in interactive and non-interactive mode.
|
||||
To exit from interactive mode press Ctrl+D.
|
||||
In interactive mode,
|
||||
if sdcv was compiled with readline library support,
|
||||
you can use UP and DOWN keys to work through history.
|
||||
you can use the UP and DOWN keys to cycle through history.
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
.B "\-h \-\-help"
|
||||
display help message and exit
|
||||
Display help message and exit
|
||||
.TP 8
|
||||
.B "\-v \-\-verbose"
|
||||
display version and exit
|
||||
Display version and exit
|
||||
.TP 8
|
||||
.B "\-l \-\-list\-dicts"
|
||||
display list of available dictionaries and exit
|
||||
Display list of available dictionaries and exit
|
||||
.TP 8
|
||||
.B "\-u \-\-use\-dict filename"
|
||||
for search use only dictionary with this bookname
|
||||
For search use only dictionary with this bookname
|
||||
.TP 8
|
||||
.B "\-n \-\-non\-interactive"
|
||||
for use in scripts
|
||||
For use in scripts
|
||||
.TP 8
|
||||
.B "\-x \-\-only\-data\-dir"
|
||||
For use in scripts: only use the dictionaries in data-dir, do not search in user and system directories
|
||||
.TP 8
|
||||
.B "\-e \-\-exact\-search"
|
||||
Do not fuzzy-search for similar words, only return exact matches
|
||||
.TP 8
|
||||
.B "\-j \-\-json"
|
||||
Print the results of list-dicts and searches as json, not as plain text.
|
||||
For use in automatically processing the results of a dictionary lookup.
|
||||
.TP 8
|
||||
.B "\-\-utf8\-output"
|
||||
Force sdcv not use conversation to locale charset, output in utf8
|
||||
Force sdcv to not convert to locale charset, output in utf8
|
||||
.TP 8
|
||||
.B "\-\-utf8\-input"
|
||||
Force sdcv not use conversation from locale charset, suppose that
|
||||
input in utf8
|
||||
Force sdcv to not convert from locale charset, assume that
|
||||
input is in utf8
|
||||
.TP 8
|
||||
.B "\-\-data\-dir path/to/directory"
|
||||
Use this directory as path to stardict data directory. This is mean that
|
||||
sdcv search dictionaries in data-dir/dic directory.
|
||||
Use this directory as the path to the stardict data directory. This means that
|
||||
sdcv searches for dictionaries in data-dir/dic directory.
|
||||
.TP 8
|
||||
.B "\-\-color"
|
||||
Use ANSI escape code for colorize sdcv output
|
||||
Use ANSI escape codes for colorizing sdcv output (does not work with json output).
|
||||
.SH FILES
|
||||
.TP
|
||||
/usr/share/stardict/dic
|
||||
.TP
|
||||
$(HOME)/.stardict/dic
|
||||
|
||||
Place, where sdcv expect to find dictionaries.
|
||||
Instead of /usr/share/stardict/dic you can use everything
|
||||
that you want, just set STARDICT_DATA_DIR environment variable.
|
||||
Place where sdcv expects to find dictionaries.
|
||||
Instead of /usr/share/stardict/dic you can use any directory
|
||||
you want, just set the STARDICT_DATA_DIR environment variable.
|
||||
For example, if you have dictionaries in /mnt/data/stardict-dicts/dic,
|
||||
set STARDICT_DATA_DIR to /mnt/data/stardict-dicts.
|
||||
.TP
|
||||
$(HOME)/.sdcv_history
|
||||
|
||||
This file include last $(SDCV_HISTSIZE) words, which you seek with sdcv.
|
||||
SDCV use this file only if it was compiled with readline library support.
|
||||
This file includes the last $(SDCV_HISTSIZE) words, which you sought with sdcv.
|
||||
SDCV uses this file only if it was compiled with readline library support.
|
||||
.TP
|
||||
$(HOME)/.sdcv_ordering
|
||||
|
||||
This is a text file containing one dictionary bookname per line.
|
||||
It specifies in which order the results of a search should be shown.
|
||||
.SH ENVIRONMENT
|
||||
Environment Variables Used By \fIsdcv\fR:
|
||||
.TP 20
|
||||
.B STARDICT_DATA_DIR
|
||||
If set, sdcv use this variable as data directory, this is mean that sdcv
|
||||
search dictionaries in $\fBSTARDICT_DATA_DIR\fR\\dic
|
||||
If set, sdcv uses this variable as the data directory, this means that sdcv
|
||||
searches dictionaries in $\fBSTARDICT_DATA_DIR\fR\\dic
|
||||
.TP 20
|
||||
.B SDCV_HISTSIZE
|
||||
If set, sdcv wrote in $(HOME)/.sdcv_history only last $(SDCV_HISTSIZE) words,
|
||||
which you seek using sdcv. If it is not set, then last 2000 words saved in $(HOME)/.sdcv_history.
|
||||
If set, sdcv writes in $(HOME)/.sdcv_history the last $(SDCV_HISTSIZE) words,
|
||||
which you look up using sdcv. If it is not set, then the last 2000 words are saved in $(HOME)/.sdcv_history.
|
||||
.TP 20
|
||||
.B SDCV_PAGER
|
||||
If SDCV_PAGER is set, its value is used as the name of the program
|
||||
to use to display the dictionary's article.
|
||||
to use to display the dictionary article.
|
||||
.SH BUGS
|
||||
Email bug reports to dushistov at mail dot ru. Be sure to include the word
|
||||
"sdcv" somewhere in the "Subject:" field.
|
||||
|
||||
188
po/cs.po
188
po/cs.po
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.4.2\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2008-09-24 10:42+0200\n"
|
||||
"Last-Translator: Michal Čihař <michal@cihar.com>\n"
|
||||
"Language-Team: Czech <cs@li.org>\n"
|
||||
@@ -16,102 +16,25 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#: src/sdcv.cpp:108
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version zobrazí informace o verzi a skončí\n"
|
||||
|
||||
#: src/sdcv.cpp:110
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "-l, --list-dicts zobrazí seznam dostupných slovníků a skončí\n"
|
||||
|
||||
#: src/sdcv.cpp:112
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict jméno vyhledávat jen v zadaném slovníku\n"
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:115
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:117
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output výstup musí být v utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:119
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input vstup musí být v utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:121
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir cesta/někam použít tento adresář jako cestu ke slovníkům "
|
||||
"stardict\n"
|
||||
|
||||
#: src/sdcv.cpp:122
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:129
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:135
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:141
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Konzolová verze Stardictu, verze %s\n"
|
||||
|
||||
#: src/sdcv.cpp:170
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "Jméno slovníku Počet slov\n"
|
||||
|
||||
#: src/sdcv.cpp:192
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir selhalo: %s\n"
|
||||
|
||||
#: src/sdcv.cpp:208
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Zadejte slovo nebo frázi: "
|
||||
|
||||
#: src/sdcv.cpp:216
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Nebyla zadáno nic k přeložení.\n"
|
||||
|
||||
#: src/libwrapper.cpp:248
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr "popen selhalo"
|
||||
|
||||
#: src/libwrapper.cpp:285 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "Nepodařilo se převést %s do utf8.\n"
|
||||
|
||||
#: src/libwrapper.cpp:342 src/libwrapper.cpp:370
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, fuzzy, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "Nalezeno %d záznamů podobných %s.\n"
|
||||
|
||||
#: src/libwrapper.cpp:356
|
||||
#: ../src/libwrapper.cpp:416
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "Vaše volba [-1 pro ukončení]: "
|
||||
|
||||
#: src/libwrapper.cpp:365
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
@@ -120,12 +43,107 @@ msgstr ""
|
||||
"Chybná volba.\n"
|
||||
"Musí být mezi 0 a %d nebo -1.\n"
|
||||
|
||||
#: src/libwrapper.cpp:381
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "Nic podobného %s nenalezeno, promiň :(\n"
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version zobrazí informace o verzi a skončí\n"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "-l, --list-dicts zobrazí seznam dostupných slovníků a skončí\n"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict jméno vyhledávat jen v zadaném slovníku\n"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output výstup musí být v utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input vstup musí být v utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir cesta/někam použít tento adresář jako cestu ke slovníkům "
|
||||
"stardict\n"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Konzolová verze Stardictu, verze %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir selhalo: %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Zadejte slovo nebo frázi: "
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Nebyla zadáno nic k přeložení.\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "Jméno slovníku Počet slov\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, fuzzy, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "Nepodařilo se převést %s do utf8.\n"
|
||||
|
||||
198
po/fr.po
198
po/fr.po
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.4.2\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2009-06-15 23:20+0800\n"
|
||||
"Language-Team: Vincent Petry <PVince81@yahoo.fr>\n"
|
||||
"Language: \n"
|
||||
@@ -18,107 +18,25 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: src/sdcv.cpp:108
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr ""
|
||||
"-v, --version afficher les informations de version et sortir\n"
|
||||
|
||||
#: src/sdcv.cpp:110
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
"-l, --list-dicts afficher la liste des dictionnaires disponibles et "
|
||||
"sortir\n"
|
||||
|
||||
#: src/sdcv.cpp:112
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr ""
|
||||
"-u, --use-dict nom_dict pour chercher seulement en utilisant le "
|
||||
"dictionnaire spécifié\n"
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:115
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:117
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output force la sortie au format utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:119
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input force l'entrée de sdcv au format utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:121
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir chemin utiliser ce chemin pour trouver les données de "
|
||||
"stardict\n"
|
||||
|
||||
#: src/sdcv.cpp:122
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:129
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:135
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:141
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Version console de Stardict, version %s\n"
|
||||
|
||||
#: src/sdcv.cpp:170
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "Nom dictionnaire Nombre de mots\n"
|
||||
|
||||
#: src/sdcv.cpp:192
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "Échec de g_mkdir : %s\n"
|
||||
|
||||
#: src/sdcv.cpp:208
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Entrez un mot ou une phrase: "
|
||||
|
||||
#: src/sdcv.cpp:216
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Il n'y a pas de mots/phrases à traduire.\n"
|
||||
|
||||
#: src/libwrapper.cpp:248
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr "Échec de popen"
|
||||
|
||||
#: src/libwrapper.cpp:285 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "Ne peut convertir %s au format utf8.\n"
|
||||
|
||||
#: src/libwrapper.cpp:342 src/libwrapper.cpp:370
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, fuzzy, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "Trouvé %d éléments similaires à %s.\n"
|
||||
|
||||
#: src/libwrapper.cpp:356
|
||||
#: ../src/libwrapper.cpp:416
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "Votre choix[-1 pour abandonner] : "
|
||||
|
||||
#: src/libwrapper.cpp:365
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
@@ -127,12 +45,112 @@ msgstr ""
|
||||
"Selection invalide.\n"
|
||||
"Veuillez choisir un nombre entre 0 et %d, ou -1.\n"
|
||||
|
||||
#: src/libwrapper.cpp:381
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "Aucun mot/phrase similaire à %s, désolé :(\n"
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr ""
|
||||
"-v, --version afficher les informations de version et sortir\n"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
"-l, --list-dicts afficher la liste des dictionnaires disponibles et "
|
||||
"sortir\n"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr ""
|
||||
"-u, --use-dict nom_dict pour chercher seulement en utilisant le "
|
||||
"dictionnaire spécifié\n"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output force la sortie au format utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input force l'entrée de sdcv au format utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir chemin utiliser ce chemin pour trouver les données de "
|
||||
"stardict\n"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Version console de Stardict, version %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "Échec de g_mkdir : %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Entrez un mot ou une phrase: "
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Il n'y a pas de mots/phrases à traduire.\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "Nom dictionnaire Nombre de mots\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "Ne peut pas convertir %s dans la locale courante.\n"
|
||||
|
||||
180
po/ru.po
180
po/ru.po
@@ -8,8 +8,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.5\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"PO-Revision-Date: 2013-07-07 18:49+0400\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2017-08-16 10:05+0300\n"
|
||||
"Last-Translator: Evgeniy Dushistov <dushistov@mail.ru>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"Language: ru\n"
|
||||
@@ -19,99 +19,25 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: src/sdcv.cpp:80
|
||||
msgid "display version information and exit"
|
||||
msgstr "показать номер версии и завершить работу"
|
||||
|
||||
#: src/sdcv.cpp:82
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "показать список доступных словарей и завершить работу"
|
||||
|
||||
#: src/sdcv.cpp:84
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "для поиска использовать только этот словарь с таким именем"
|
||||
|
||||
#: src/sdcv.cpp:85
|
||||
msgid "bookname"
|
||||
msgstr "имя_словаря"
|
||||
|
||||
#: src/sdcv.cpp:87
|
||||
msgid "for use in scripts"
|
||||
msgstr "для использования в скриптах"
|
||||
|
||||
#: src/sdcv.cpp:89
|
||||
msgid "output must be in utf8"
|
||||
msgstr "вывод программы должен быть в utf8"
|
||||
|
||||
#: src/sdcv.cpp:91
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "ввод программы в utf8"
|
||||
|
||||
#: src/sdcv.cpp:93
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"использовать эту директорию в качестве пути к \"stardict data\" директории"
|
||||
|
||||
#: src/sdcv.cpp:94
|
||||
msgid "path/to/dir"
|
||||
msgstr "путь/до/директории"
|
||||
|
||||
#: src/sdcv.cpp:96
|
||||
msgid "colorize the output"
|
||||
msgstr "раскрашивать вывод в разные цвета"
|
||||
|
||||
#: src/sdcv.cpp:101
|
||||
msgid " words"
|
||||
msgstr "слова"
|
||||
|
||||
#: src/sdcv.cpp:107
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr "Неправильный аргумент командой строки: %s\n"
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Консольная версия StarDict, версия %s\n"
|
||||
|
||||
#: src/sdcv.cpp:139
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "Название словаря Количество слов\n"
|
||||
|
||||
#: src/sdcv.cpp:174
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir завершился с ошибкой: %s\n"
|
||||
|
||||
#: src/sdcv.cpp:189
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Введите слово или фразу: "
|
||||
|
||||
#: src/sdcv.cpp:197
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Не задано слова/фразы для перевода.\n"
|
||||
|
||||
#: src/libwrapper.cpp:280
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr "функция popen завершилась с ошибкой"
|
||||
|
||||
#: src/libwrapper.cpp:317 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "Не могу преобразовать %s в utf8.\n"
|
||||
|
||||
#: src/libwrapper.cpp:371 src/libwrapper.cpp:402
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "Найдено %zu слов, похожих на %s.\n"
|
||||
|
||||
#: src/libwrapper.cpp:388
|
||||
#: ../src/libwrapper.cpp:416
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "Ваш выбор[-1 - отмена]: "
|
||||
|
||||
#: src/libwrapper.cpp:397
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
@@ -120,12 +46,100 @@ msgstr ""
|
||||
"Неправильный выбор.\n"
|
||||
"Должно быть от 0 до %zu или -1.\n"
|
||||
|
||||
#: src/libwrapper.cpp:413
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "Ничего похожего на %s, извините :(\n"
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
msgid "display version information and exit"
|
||||
msgstr "показать номер версии и завершить работу"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "показать список доступных словарей и завершить работу"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "для поиска использовать только этот словарь с таким именем"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr "имя_словаря"
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr "для использования в скриптах"
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr "выдать результат в JSON формате"
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr "не использовать нечеткий поиск похожих слов, вернуть только точные совпадения"
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
msgid "output must be in utf8"
|
||||
msgstr "вывод программы должен быть в utf8"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "ввод программы в utf8"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"использовать эту директорию в качестве пути к \"stardict data\" директории"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr "путь/до/директории"
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr "использовать словари только из data-dir, не искать в пользовательских и системных каталогах"
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr "раскрашивать вывод в разные цвета"
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr "слова"
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr "Неправильный аргумент командой строки: %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Консольная версия StarDict, версия %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir завершился с ошибкой: %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Введите слово или фразу: "
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Не задано слова/фразы для перевода.\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "Название словаря Количество слов\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "Не могу преобразовать %s в локальную кодировку.\n"
|
||||
|
||||
179
po/sdcv.pot
179
po/sdcv.pot
@@ -7,118 +7,133 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.5\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2017-08-16 10:01+0300\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/sdcv.cpp:76
|
||||
msgid "display version information and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:78
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:84
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:85
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:87
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:89
|
||||
msgid "output must be in utf8"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:91
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:93
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:94
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:96
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:101
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:107
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:139
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:174
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:189
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:197
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:280
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:317 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:371 src/libwrapper.cpp:402
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:388
|
||||
#: ../src/libwrapper.cpp:416
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:397
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
"It must be from 0 to %zu or -1.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:413
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
msgid "display version information and exit"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
msgid "output must be in utf8"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr ""
|
||||
|
||||
190
po/sk.po
190
po/sk.po
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.3.2\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2007-09-11 00:22+0100\n"
|
||||
"Last-Translator: Ivan Masár <helix84@centrum.sk>\n"
|
||||
"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
|
||||
@@ -18,104 +18,26 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: src/sdcv.cpp:108
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version zobrazí informácie o verzii a skončí\n"
|
||||
|
||||
#: src/sdcv.cpp:110
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
"-l, --list-dicts zobrazí zoznam dostupných slovníkov a skončí\n"
|
||||
|
||||
#: src/sdcv.cpp:112
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict názov použiť pre hľadanie iba zvolený slovník\n"
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:115
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:117
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output výstup musí byť v utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:119
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input vstup pre sdcv je v utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:121
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir path/to/dir použiť tento priečinok ako cestu pre stardict "
|
||||
"dátový priečinok\n"
|
||||
|
||||
#: src/sdcv.cpp:122
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:129
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:135
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:141
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Konzolová verzia StarDict, verzia %s\n"
|
||||
|
||||
#: src/sdcv.cpp:170
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "názov slovníka počet slov\n"
|
||||
|
||||
#: src/sdcv.cpp:192
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir zlyhalo: %s\n"
|
||||
|
||||
#: src/sdcv.cpp:208
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Vložte slovo alebo frázu: "
|
||||
|
||||
#: src/sdcv.cpp:216
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Nie je čo preložiť.\n"
|
||||
|
||||
#: src/libwrapper.cpp:248
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr "popen zlyhalo"
|
||||
|
||||
#: src/libwrapper.cpp:285 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "nie je možné konvertovať %s na utf8.\n"
|
||||
|
||||
#: src/libwrapper.cpp:342 src/libwrapper.cpp:370
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, fuzzy, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "Nájdené %d položiek, podobných %s,\n"
|
||||
|
||||
#: src/libwrapper.cpp:356
|
||||
#: ../src/libwrapper.cpp:416
|
||||
#, fuzzy
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "Vaša voľba[-1 zruší]: "
|
||||
|
||||
#: src/libwrapper.cpp:365
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
@@ -124,12 +46,108 @@ msgstr ""
|
||||
"Neplatná voľba.\n"
|
||||
"Musí byť od 0 do %d alebo -1.\n"
|
||||
|
||||
#: src/libwrapper.cpp:381
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "Ľutujem, nič sa nepodobá na %s :(\n"
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version zobrazí informácie o verzii a skončí\n"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
"-l, --list-dicts zobrazí zoznam dostupných slovníkov a skončí\n"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict názov použiť pre hľadanie iba zvolený slovník\n"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output výstup musí byť v utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input vstup pre sdcv je v utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir path/to/dir použiť tento priečinok ako cestu pre stardict "
|
||||
"dátový priečinok\n"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Konzolová verzia StarDict, verzia %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir zlyhalo: %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "Vložte slovo alebo frázu: "
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Nie je čo preložiť.\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "názov slovníka počet slov\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "Nie je možné konvertovať %s na aktuálne locale.\n"
|
||||
|
||||
194
po/uk.po
194
po/uk.po
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.3\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2004-12-14 17:54+0300\n"
|
||||
"Last-Translator: <dubyk@lsl.lviv.ua>\n"
|
||||
"Language-Team: Ukrainian <dubyk@lsl.lviv.ua>\n"
|
||||
@@ -19,106 +19,26 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: src/sdcv.cpp:108
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version показати номер версії і завершити роботу\n"
|
||||
|
||||
#: src/sdcv.cpp:110
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
"-l, --list-dicts показати список доступних словників і завершити "
|
||||
"роботу\n"
|
||||
|
||||
#: src/sdcv.cpp:112
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr ""
|
||||
"-u, --use-dict ім`я словника для пошуку використовувати лише цей словник\n"
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:115
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:117
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output вивід програми повинен бути в utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:119
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input ввід програми в utf8\n"
|
||||
|
||||
#: src/sdcv.cpp:121
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir тека використовувати цю теку як шлях до stardict data "
|
||||
"directory\n"
|
||||
|
||||
#: src/sdcv.cpp:122
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:129
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:135
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:141
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Консольна версія Зоряного словника [Stardict], номер версії %s\n"
|
||||
|
||||
#: src/sdcv.cpp:170
|
||||
#, fuzzy, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "назва словника кількість слів\n"
|
||||
|
||||
#: src/sdcv.cpp:192
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:208
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "ВведЁть слово або фразу: "
|
||||
|
||||
#: src/sdcv.cpp:216
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Не задано слова/фрази для перекладу.\n"
|
||||
|
||||
#: src/libwrapper.cpp:248
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:285 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "Не можу перетворити %s у utf8.\n"
|
||||
|
||||
#: src/libwrapper.cpp:342 src/libwrapper.cpp:370
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, fuzzy, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "Знайдено %d слів, схожих на %s.\n"
|
||||
|
||||
#: src/libwrapper.cpp:356
|
||||
#: ../src/libwrapper.cpp:416
|
||||
#, fuzzy
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "Ваш вибір: "
|
||||
|
||||
#: src/libwrapper.cpp:365
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
@@ -127,12 +47,110 @@ msgstr ""
|
||||
"Неправильний вибір.\n"
|
||||
"Повинно бути від 0 до %d.\n"
|
||||
|
||||
#: src/libwrapper.cpp:381
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "Нічого схожого на %s, даруйте :(\n"
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version показати номер версії і завершити роботу\n"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr ""
|
||||
"-l, --list-dicts показати список доступних словників і завершити "
|
||||
"роботу\n"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr ""
|
||||
"-u, --use-dict ім`я словника для пошуку використовувати лише цей словник\n"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output вивід програми повинен бути в utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input ввід програми в utf8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr ""
|
||||
"--data-dir тека використовувати цю теку як шлях до stardict data "
|
||||
"directory\n"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Консольна версія Зоряного словника [Stardict], номер версії %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "ВведЁть слово або фразу: "
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "Не задано слова/фрази для перекладу.\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, fuzzy, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "назва словника кількість слів\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "Не можу перетворити %s у локальне кодування.\n"
|
||||
|
||||
184
po/zh_CN.po
184
po/zh_CN.po
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.3\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2008-09-24 10:54+0200\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2005-1-17 00:58+0800\n"
|
||||
"Last-Translator: Cai Qian <caiqian@gnome.org>\n"
|
||||
"Language-Team: Simplified Chinese\n"
|
||||
@@ -15,101 +15,26 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/sdcv.cpp:108
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version 显示版本信息并退出\n"
|
||||
|
||||
#: src/sdcv.cpp:110
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "-l, --list-dicts 显示可用的字典列表并退出\n"
|
||||
|
||||
#: src/sdcv.cpp:112
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict 字典名 只使用指定的字典进行单词搜索\n"
|
||||
|
||||
#: src/sdcv.cpp:113
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:115
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:117
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output 输出必须是 UTF-8\n"
|
||||
|
||||
#: src/sdcv.cpp:119
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input sdcv 的输入为 UTF-8\n"
|
||||
|
||||
#: src/sdcv.cpp:121
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr "--data-dir 目录路径 指定 Stardict 数据所在目录的路径\n"
|
||||
|
||||
#: src/sdcv.cpp:122
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:129
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:135
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:141
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Stardict 的控制台版本,版本为 %s\n"
|
||||
|
||||
#: src/sdcv.cpp:170
|
||||
#, fuzzy, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "字典名 单词量\n"
|
||||
|
||||
#: src/sdcv.cpp:192
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/sdcv.cpp:208
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "请输入单词或短语:"
|
||||
|
||||
#: src/sdcv.cpp:216
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "没有供翻译的单词或短语。\n"
|
||||
|
||||
#: src/libwrapper.cpp:248
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/libwrapper.cpp:285 src/utils.cpp:67
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "无法将 %s 转换为 UTF-8。\n"
|
||||
|
||||
#: src/libwrapper.cpp:342 src/libwrapper.cpp:370
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, fuzzy, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "发现 %d 条记录和 %s 相似。\n"
|
||||
|
||||
#: src/libwrapper.cpp:356
|
||||
#: ../src/libwrapper.cpp:416
|
||||
#, fuzzy
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "您的选择为:"
|
||||
|
||||
#: src/libwrapper.cpp:365
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"Invalid choice.\n"
|
||||
@@ -118,12 +43,105 @@ msgstr ""
|
||||
"无效的选择。\n"
|
||||
"必须是 0 到 %d。\n"
|
||||
|
||||
#: src/libwrapper.cpp:381
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "对不起,没有发现和 %s 相似的 :(\n"
|
||||
|
||||
#: src/utils.cpp:45
|
||||
#: ../src/sdcv.cpp:88
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version 显示版本信息并退出\n"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "-l, --list-dicts 显示可用的字典列表并退出\n"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict 字典名 只使用指定的字典进行单词搜索\n"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output 输出必须是 UTF-8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input sdcv 的输入为 UTF-8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr "--data-dir 目录路径 指定 Stardict 数据所在目录的路径\n"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Stardict 的控制台版本,版本为 %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "请输入单词或短语:"
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "没有供翻译的单词或短语。\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, fuzzy, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "字典名 单词量\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "无法将 %s 转换为当前 Locale。\n"
|
||||
|
||||
218
po/zh_TW.po
218
po/zh_TW.po
@@ -8,122 +8,158 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sdcv 0.4.2\n"
|
||||
"Report-Msgid-Bugs-To: dushistov@mail.ru\n"
|
||||
"POT-Creation-Date: 2006-04-24 15:18+0400\n"
|
||||
"POT-Creation-Date: 2017-08-16 09:52+0300\n"
|
||||
"PO-Revision-Date: 2013-06-12 14:11+0800\n"
|
||||
"Last-Translator: Wei-Lun Chao <bluebat@member.fsf.org>\n"
|
||||
"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
|
||||
"Language: zh_TW\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Unknown option.\n"
|
||||
"Try '%s --help' for more information.\n"
|
||||
msgstr ""
|
||||
"不明選項。\n"
|
||||
"更多資訊請看 '%s --help'。\n"
|
||||
|
||||
#: src/sdcv.cpp:134
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTIONS] words\n"
|
||||
msgstr "用法:%s [選項] 單字…\n"
|
||||
|
||||
#: src/sdcv.cpp:135
|
||||
#, c-format
|
||||
msgid "-h, --help display this help and exit\n"
|
||||
msgstr "-h, --help 顯示本輔助並離開\n"
|
||||
|
||||
#: src/sdcv.cpp:136
|
||||
#, c-format
|
||||
msgid "-v, --version display version information and exit\n"
|
||||
msgstr "-v, --version 顯示版本資訊並離開\n"
|
||||
|
||||
#: src/sdcv.cpp:137
|
||||
#, c-format
|
||||
msgid "-l, --list-dicts display list of available dictionaries and exit\n"
|
||||
msgstr "-l, --list-dicts 顯示可用的字典清單並離開\n"
|
||||
|
||||
#: src/sdcv.cpp:138
|
||||
#, c-format
|
||||
msgid "-u, --use-dict bookname for search use only dictionary with this bookname\n"
|
||||
msgstr "-u, --use-dict 字典名 只使用指定的字典進行單字搜尋\n"
|
||||
|
||||
#: src/sdcv.cpp:139
|
||||
#, c-format
|
||||
msgid "-n, --non-interactive for use in scripts\n"
|
||||
msgstr "-n, --non-interactive 在指令稿中使用\n"
|
||||
|
||||
#: src/sdcv.cpp:140
|
||||
#, c-format
|
||||
msgid "--utf8-output output must be in utf8\n"
|
||||
msgstr "--utf8-output 輸出必須是 UTF-8\n"
|
||||
|
||||
#: src/sdcv.cpp:141
|
||||
#, c-format
|
||||
msgid "--utf8-input input of sdcv in utf8\n"
|
||||
msgstr "--utf8-input sdcv 的輸入為 UTF-8\n"
|
||||
|
||||
#: src/sdcv.cpp:142
|
||||
#, c-format
|
||||
msgid "--data-dir path/to/dir use this directory as path to stardict data directory\n"
|
||||
msgstr "--data-dir 目錄路徑 指定 Stardict 資料所在目錄的路徑\n"
|
||||
|
||||
#: src/sdcv.cpp:148
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Stardict 的主控臺版本,版本為 %s\n"
|
||||
|
||||
#: src/sdcv.cpp:169
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "字典名稱 單字數量\n"
|
||||
|
||||
#: src/sdcv.cpp:191
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir 失敗:%s\n"
|
||||
|
||||
#: src/sdcv.cpp:207
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "請輸入單字或片語:"
|
||||
|
||||
#: src/sdcv.cpp:215
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "沒有可供翻譯的單字或片語。\n"
|
||||
|
||||
#: src/libwrapper.cpp:245
|
||||
#: ../src/libwrapper.cpp:300
|
||||
msgid "popen failed"
|
||||
msgstr "popen 失敗"
|
||||
|
||||
#: src/libwrapper.cpp:282
|
||||
#: ../src/libwrapper.cpp:340
|
||||
#, c-format
|
||||
msgid "Can not convert %s to utf8.\n"
|
||||
msgstr "無法將 %s 轉換為 UTF-8。\n"
|
||||
|
||||
#: src/libwrapper.cpp:339 src/libwrapper.cpp:371
|
||||
#, c-format
|
||||
msgid "Found %d items, similar to %s.\n"
|
||||
#: ../src/libwrapper.cpp:398 ../src/libwrapper.cpp:432
|
||||
#, fuzzy, c-format
|
||||
msgid "Found %zu items, similar to %s.\n"
|
||||
msgstr "找到 %d 項紀錄和 %s 相似。\n"
|
||||
|
||||
#: src/libwrapper.cpp:352
|
||||
#, c-format
|
||||
#: ../src/libwrapper.cpp:416
|
||||
msgid "Your choice[-1 to abort]: "
|
||||
msgstr "您的選擇是[-1 表示放棄]:"
|
||||
|
||||
#: src/libwrapper.cpp:366
|
||||
#, c-format
|
||||
#: ../src/libwrapper.cpp:426
|
||||
#, fuzzy, c-format
|
||||
msgid ""
|
||||
"Invalid choise.\n"
|
||||
"It must be from 0 to %d or -1.\n"
|
||||
"Invalid choice.\n"
|
||||
"It must be from 0 to %zu or -1.\n"
|
||||
msgstr ""
|
||||
"無效的選擇。\n"
|
||||
"必須是 0 到 %d 之間或 -1。\n"
|
||||
|
||||
#: src/libwrapper.cpp:382
|
||||
#: ../src/libwrapper.cpp:445
|
||||
#, c-format
|
||||
msgid "Nothing similar to %s, sorry :(\n"
|
||||
msgstr "抱歉,沒有和 %s 相似者 :(\n"
|
||||
|
||||
#: ../src/sdcv.cpp:88
|
||||
#, fuzzy
|
||||
msgid "display version information and exit"
|
||||
msgstr "-v, --version 顯示版本資訊並離開\n"
|
||||
|
||||
#: ../src/sdcv.cpp:90
|
||||
#, fuzzy
|
||||
msgid "display list of available dictionaries and exit"
|
||||
msgstr "-l, --list-dicts 顯示可用的字典清單並離開\n"
|
||||
|
||||
#: ../src/sdcv.cpp:92
|
||||
#, fuzzy
|
||||
msgid "for search use only dictionary with this bookname"
|
||||
msgstr "-u, --use-dict 字典名 只使用指定的字典進行單字搜尋\n"
|
||||
|
||||
#: ../src/sdcv.cpp:93
|
||||
msgid "bookname"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:95
|
||||
msgid "for use in scripts"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:97
|
||||
msgid "print the result formatted as JSON"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:99
|
||||
msgid "do not fuzzy-search for similar words, only return exact matches"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:101
|
||||
#, fuzzy
|
||||
msgid "output must be in utf8"
|
||||
msgstr "--utf8-output 輸出必須是 UTF-8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:103
|
||||
#, fuzzy
|
||||
msgid "input of sdcv in utf8"
|
||||
msgstr "--utf8-input sdcv 的輸入為 UTF-8\n"
|
||||
|
||||
#: ../src/sdcv.cpp:105
|
||||
#, fuzzy
|
||||
msgid "use this directory as path to stardict data directory"
|
||||
msgstr "--data-dir 目錄路徑 指定 Stardict 資料所在目錄的路徑\n"
|
||||
|
||||
#: ../src/sdcv.cpp:106
|
||||
msgid "path/to/dir"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:108
|
||||
msgid ""
|
||||
"only use the dictionaries in data-dir, do not search in user and system "
|
||||
"directories"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:110
|
||||
msgid "colorize the output"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:115
|
||||
msgid " words"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:121
|
||||
#, c-format
|
||||
msgid "Invalid command line arguments: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/sdcv.cpp:127
|
||||
#, c-format
|
||||
msgid "Console version of Stardict, version %s\n"
|
||||
msgstr "Stardict 的主控臺版本,版本為 %s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:202
|
||||
#, c-format
|
||||
msgid "g_mkdir failed: %s\n"
|
||||
msgstr "g_mkdir 失敗:%s\n"
|
||||
|
||||
#: ../src/sdcv.cpp:217
|
||||
msgid "Enter word or phrase: "
|
||||
msgstr "請輸入單字或片語:"
|
||||
|
||||
#: ../src/sdcv.cpp:225
|
||||
#, c-format
|
||||
msgid "There are no words/phrases to translate.\n"
|
||||
msgstr "沒有可供翻譯的單字或片語。\n"
|
||||
|
||||
#: ../src/sdcv.cpp:237
|
||||
#, c-format
|
||||
msgid "Dictionary's name Word count\n"
|
||||
msgstr "字典名稱 單字數量\n"
|
||||
|
||||
#: ../src/utils.cpp:48
|
||||
#, fuzzy, c-format
|
||||
msgid "Can not convert %s to current locale.\n"
|
||||
msgstr "無法將 %s 轉換為 UTF-8。\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Unknown option.\n"
|
||||
#~ "Try '%s --help' for more information.\n"
|
||||
#~ msgstr ""
|
||||
#~ "不明選項。\n"
|
||||
#~ "更多資訊請看 '%s --help'。\n"
|
||||
|
||||
#~ msgid "Usage: %s [OPTIONS] words\n"
|
||||
#~ msgstr "用法:%s [選項] 單字…\n"
|
||||
|
||||
#~ msgid "-h, --help display this help and exit\n"
|
||||
#~ msgstr "-h, --help 顯示本輔助並離開\n"
|
||||
|
||||
#~ msgid "-n, --non-interactive for use in scripts\n"
|
||||
#~ msgstr "-n, --non-interactive 在指令稿中使用\n"
|
||||
|
||||
116
src/core.rs
116
src/core.rs
@@ -1,116 +0,0 @@
|
||||
use ini::Ini;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::error::Error;
|
||||
use index::DictionaryIndex;
|
||||
use index::MemoryDictionaryIndex;
|
||||
use index::DiskDictionaryIndex;
|
||||
use data::DictionaryData;
|
||||
use data::SimpleDictionaryData;
|
||||
|
||||
pub struct Dictionary {
|
||||
ifo_file_name: PathBuf,
|
||||
wordcount : usize,
|
||||
bookname: String,
|
||||
sametypesequence: String,
|
||||
index: Box<DictionaryIndex>,
|
||||
data: Box<DictionaryData>
|
||||
}
|
||||
|
||||
impl Dictionary {
|
||||
pub fn new(ifo_file_name: &Path) -> Result<Dictionary, String> {
|
||||
let basename = try!(try!(ifo_file_name.file_stem().ok_or("bad ifo file name")).to_str().ok_or("can not convert file name to unicode"));
|
||||
let dict_dir = try!(ifo_file_name.parent().ok_or("bad ifo directory name"));
|
||||
|
||||
let mut file = try!(File::open(ifo_file_name).map_err(|err| err.to_string()));
|
||||
let mut ifo_content = String::new();
|
||||
match file.read_to_string(&mut ifo_content) {
|
||||
Ok(read_bytes) => { if read_bytes < 3 { return Result::Err("ifo file too small".to_string()) } },
|
||||
Result::Err(err) => return Result::Err(err.to_string())
|
||||
};
|
||||
|
||||
let content =
|
||||
if ifo_content.starts_with("\u{feff}") {
|
||||
&ifo_content[1..]
|
||||
} else {
|
||||
&ifo_content[0..]
|
||||
};
|
||||
|
||||
static DICT_MAGIC_DATA: &'static str = "StarDict's dict ifo file";
|
||||
if !content.starts_with(DICT_MAGIC_DATA) {
|
||||
return Result::Err("ifo magic not match".to_string());
|
||||
}
|
||||
|
||||
let ifo_cfg = try!(Ini::load_from_str(content).map_err(|err| err.msg));
|
||||
let section = try!(ifo_cfg.section(None::<String>).ok_or("ifo: parse none section error".to_string()));
|
||||
|
||||
let wordcount = try!(section.get("wordcount").ok_or("no wordcount".to_string()));
|
||||
let wordcount = try!(wordcount.parse::<usize>().map_err(|err| err.description().to_string()));
|
||||
let idxfilesize = try!(section.get("idxfilesize").ok_or("no idxfilesize".to_string()));
|
||||
let bookname = try!(section.get("bookname").ok_or("no bookname".to_string()));
|
||||
let sametypesequence = try!(section.get("sametypesequence").ok_or("no sametypesequence".to_string()));
|
||||
|
||||
let idx_path = dict_dir.join(basename.to_string() + ".idx");
|
||||
let idx_path_gz = dict_dir.join(basename.to_string() + ".idx.gz");
|
||||
let mut index: Box<DictionaryIndex>;
|
||||
if idx_path.exists() && idx_path.is_file() {
|
||||
let disk_dict = try!(DiskDictionaryIndex::new(wordcount, &idx_path));
|
||||
index = Box::new(disk_dict);
|
||||
} else if idx_path_gz.exists() && idx_path_gz.is_file() {
|
||||
let mem_dict = try!(MemoryDictionaryIndex::new_from_gzip(wordcount, &idx_path_gz));
|
||||
index = Box::new(mem_dict);
|
||||
} else {
|
||||
return Result::Err(format!("no index file for {}", ifo_file_name.to_str().unwrap()));
|
||||
}
|
||||
|
||||
let data_path = dict_dir.join(basename.to_string() + ".dict");
|
||||
let data_path_dz = dict_dir.join(basename.to_string() + ".dict.dz");
|
||||
let mut data: Box<DictionaryData>;
|
||||
if data_path.exists() && data_path.is_file() {
|
||||
let simple_data = try!(SimpleDictionaryData::new(data_path.as_path()));
|
||||
data = Box::new(simple_data);
|
||||
} else if data_path_dz.exists() && data_path_dz.is_file() {
|
||||
return Result::Err("reading dict.dz not implemented".to_string());
|
||||
} else {
|
||||
return Result::Err(format!("no data file for {}", ifo_file_name.to_str().unwrap()));
|
||||
}
|
||||
|
||||
Result::Ok(Dictionary{ifo_file_name : ifo_file_name.to_path_buf(), wordcount : wordcount,
|
||||
bookname : bookname.clone(), sametypesequence: sametypesequence.clone(),
|
||||
index : index, data: data})
|
||||
}
|
||||
|
||||
pub fn find(&mut self, key: &str) -> Option<String> {
|
||||
match self.index.find(key) {
|
||||
Err(idx) => None,
|
||||
Ok(idx) => {
|
||||
let key_pos = self.index.get_key(idx);
|
||||
Some(self.data.get_data(key_pos.1, key_pos.2).unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn open_dict() {
|
||||
let dic = Dictionary::new(Path::new("tests/stardict-test_dict-2.4.2/test_dict.ifo")).unwrap();
|
||||
assert_eq!(dic.wordcount, 1_usize);
|
||||
assert_eq!(dic.bookname, "test_dict");
|
||||
assert_eq!(dic.sametypesequence, "x");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_in_dict() {
|
||||
let mut dic = Dictionary::new(Path::new("tests/stardict-test_dict-2.4.2/test_dict.ifo")).unwrap();
|
||||
assert_eq!(dic.find("test").unwrap(), "<k>test</k>\ntest passed");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
33
src/data.rs
33
src/data.rs
@@ -1,33 +0,0 @@
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::Seek;
|
||||
use std::path::Path;
|
||||
use std::io::SeekFrom;
|
||||
use std::str::from_utf8;
|
||||
|
||||
pub trait DictionaryData {
|
||||
fn get_data(& mut self, offset: u64, length: usize) -> Result<String, String>;
|
||||
}
|
||||
|
||||
pub struct SimpleDictionaryData {
|
||||
data_file: File,
|
||||
}
|
||||
|
||||
impl DictionaryData for SimpleDictionaryData {
|
||||
fn get_data(& mut self, offset: u64, length: usize) -> Result<String, String> {
|
||||
try!(self.data_file.seek(SeekFrom::Start(offset)).map_err(|err| err.to_string()));
|
||||
let mut buffer = Vec::<u8>::with_capacity(length);
|
||||
buffer.resize(length, 0_u8);
|
||||
try!(self.data_file.read_exact(& mut buffer).map_err(|err| err.to_string()));
|
||||
let utf8_s = try!(String::from_utf8(buffer).map_err(|err| "invalid utf-8 data in data".to_string()));
|
||||
Result::Ok(utf8_s)
|
||||
}
|
||||
}
|
||||
|
||||
impl SimpleDictionaryData {
|
||||
pub fn new(data_file_name: &Path) ->Result<SimpleDictionaryData, String> {
|
||||
let file = try!(File::open(data_file_name).map_err(|err| err.to_string()));
|
||||
Result::Ok(SimpleDictionaryData{data_file : file})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//#define HAVE_MMAP //it will defined in config.h. this can be done by configure.in with a AC_FUNC_MMAP.
|
||||
@@ -33,13 +33,12 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
#include "dictziplib.hpp"
|
||||
|
||||
#define USE_CACHE 1
|
||||
@@ -112,7 +111,6 @@
|
||||
#define DICT_GZIP 2
|
||||
#define DICT_DZIP 3
|
||||
|
||||
|
||||
int DictData::read_header(const std::string &fname, int computeCRC)
|
||||
{
|
||||
FILE *str;
|
||||
@@ -358,7 +356,6 @@ void DictData::read(char *buffer, unsigned long start, unsigned long size)
|
||||
// ("dict_data_read( %p, %lu, %lu )\n",
|
||||
//h, start, size ));
|
||||
|
||||
|
||||
switch (this->type) {
|
||||
case DICT_GZIP:
|
||||
//err_fatal( __FUNCTION__,
|
||||
|
||||
@@ -13,7 +13,8 @@ struct DictCache {
|
||||
int count;
|
||||
};
|
||||
|
||||
class DictData {
|
||||
class DictData
|
||||
{
|
||||
public:
|
||||
static const size_t DICT_CACHE_SIZE = 5;
|
||||
|
||||
@@ -22,6 +23,7 @@ public:
|
||||
bool open(const std::string &filename, int computeCRC);
|
||||
void close();
|
||||
void read(char *buffer, unsigned long start, unsigned long size);
|
||||
|
||||
private:
|
||||
const char *start; /* start of mmap'd area */
|
||||
const char *end; /* end of mmap'd area */
|
||||
@@ -52,4 +54,3 @@ private:
|
||||
|
||||
int read_header(const std::string &filename, int computeCRC);
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ The Levenshtein distance algorithm has been used in:
|
||||
* Plagiarism detection
|
||||
*/
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
@@ -68,30 +67,26 @@ int EditDistance::CalEditDistance(const gunichar *s,const gunichar *t,const int
|
||||
{
|
||||
int n = 0, m = 0, iLenDif, k, i, j, cost;
|
||||
// Remove leftmost matching portion of strings
|
||||
while ( *s && (*s==*t) )
|
||||
{
|
||||
while (*s && (*s == *t)) {
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
|
||||
while (s[n])
|
||||
{
|
||||
while (s[n]) {
|
||||
n++;
|
||||
}
|
||||
while (t[m])
|
||||
{
|
||||
while (t[m]) {
|
||||
m++;
|
||||
}
|
||||
|
||||
// Remove rightmost matching portion of strings by decrement n and m.
|
||||
while ( n && m && (*(s+n-1)==*(t+m-1)) )
|
||||
{
|
||||
n--;m--;
|
||||
while (n && m && (*(s + n - 1) == *(t + m - 1))) {
|
||||
n--;
|
||||
m--;
|
||||
}
|
||||
if (m == 0 || n == 0 || d == nullptr)
|
||||
return (m + n);
|
||||
if ( m < n )
|
||||
{
|
||||
if (m < n) {
|
||||
const gunichar *temp = s;
|
||||
int itemp = n;
|
||||
s = t;
|
||||
@@ -103,10 +98,10 @@ int EditDistance::CalEditDistance(const gunichar *s,const gunichar *t,const int
|
||||
if (iLenDif >= limit)
|
||||
return iLenDif;
|
||||
// step 1
|
||||
n++;m++;
|
||||
n++;
|
||||
m++;
|
||||
// d=(int*)malloc(sizeof(int)*m*n);
|
||||
if ( m*n > currentelements )
|
||||
{
|
||||
if (m * n > currentelements) {
|
||||
currentelements = m * n * 2; // double the request
|
||||
d = static_cast<int *>(realloc(d, sizeof(int) * currentelements));
|
||||
if (nullptr == d)
|
||||
@@ -118,11 +113,9 @@ int EditDistance::CalEditDistance(const gunichar *s,const gunichar *t,const int
|
||||
for (k = 1; k < m; k++)
|
||||
d[k * n] = k;
|
||||
// step 3
|
||||
for (i=1;i<n;i++)
|
||||
{
|
||||
for (i = 1; i < n; i++) {
|
||||
// first calculate column, d(i,j)
|
||||
for ( j=1;j<iLenDif+i;j++ )
|
||||
{
|
||||
for (j = 1; j < iLenDif + i; j++) {
|
||||
cost = s[i - 1] == t[j - 1] ? 0 : 1;
|
||||
d[j * n + i] = minimum(d[(j - 1) * n + i] + 1, d[j * n + i - 1] + 1, d[(j - 1) * n + i - 1] + cost);
|
||||
#ifdef COVER_TRANSPOSITION
|
||||
@@ -133,8 +126,7 @@ int EditDistance::CalEditDistance(const gunichar *s,const gunichar *t,const int
|
||||
}
|
||||
// second calculate row, d(k,j)
|
||||
// now j==iLenDif+i;
|
||||
for ( k=1;k<=i;k++ )
|
||||
{
|
||||
for (k = 1; k <= i; k++) {
|
||||
cost = s[k - 1] == t[j - 1] ? 0 : 1;
|
||||
d[j * n + k] = minimum(d[(j - 1) * n + k] + 1, d[j * n + k - 1] + 1, d[(j - 1) * n + k - 1] + cost);
|
||||
#ifdef COVER_TRANSPOSITION
|
||||
@@ -144,8 +136,7 @@ int EditDistance::CalEditDistance(const gunichar *s,const gunichar *t,const int
|
||||
#endif
|
||||
}
|
||||
// test if d(i,j) limit gets equal or exceed
|
||||
if ( d[j*n+i] >= limit )
|
||||
{
|
||||
if (d[j * n + i] >= limit) {
|
||||
return d[j * n + i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,24 @@
|
||||
#include <cstdlib>
|
||||
#include <glib.h>
|
||||
|
||||
class EditDistance {
|
||||
class EditDistance
|
||||
{
|
||||
public:
|
||||
EditDistance() {
|
||||
EditDistance()
|
||||
{
|
||||
currentelements = 2500; // It's enough for most conditions :-)
|
||||
d = static_cast<int *>(malloc(sizeof(int) * currentelements));
|
||||
}
|
||||
~EditDistance() {
|
||||
~EditDistance()
|
||||
{
|
||||
if (d != nullptr)
|
||||
free(d);
|
||||
}
|
||||
EditDistance(const EditDistance &) = delete;
|
||||
EditDistance &operator=(const EditDistance &) = delete;
|
||||
int CalEditDistance(const gunichar *s, const gunichar *t, const int limit);
|
||||
|
||||
private:
|
||||
int *d;
|
||||
int currentelements;
|
||||
};
|
||||
|
||||
|
||||
308
src/index.rs
308
src/index.rs
@@ -1,308 +0,0 @@
|
||||
use std::str::from_utf8;
|
||||
use std::cmp::Ordering;
|
||||
use std::io::Cursor;
|
||||
use byteorder::{NetworkEndian, ReadBytesExt};
|
||||
use mem_mapped_file::MemMappedFile;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use flate2::read::GzDecoder;
|
||||
use std::error::Error;
|
||||
|
||||
pub trait DictionaryIndex {
|
||||
fn get_key(&self, idx: usize) -> (&str, u64, usize);
|
||||
fn count(&self) -> usize;
|
||||
fn find(&self, key: &str) -> Result<usize, usize>;
|
||||
}
|
||||
|
||||
pub struct MemoryDictionaryIndex {
|
||||
idx_content: Vec<u8>,
|
||||
wordlist: Vec<usize>,
|
||||
}
|
||||
|
||||
fn g_ascii_strcasecmp(s1: &str, s2: &str) -> isize {
|
||||
fn is_upper(c: u8) -> bool { c >= b'A' && c <= b'Z' }
|
||||
fn to_lower(c: u8) -> u8 { if is_upper(c) { c - b'A' + b'a' } else { c } }
|
||||
|
||||
let mut it1 = s1.bytes();
|
||||
let mut it2 = s2.bytes();
|
||||
loop {
|
||||
match (it1.next(), it2.next()) {
|
||||
(None, None) => return 0,
|
||||
(Some(b1), None) => return b1 as isize,
|
||||
(None, Some(b2)) => return -(b2 as isize),
|
||||
(Some(b1), Some(b2)) => {
|
||||
let c1 = to_lower(b1) as isize;
|
||||
let c2 = to_lower(b2) as isize;
|
||||
if c1 != c2 {
|
||||
return c1 - c2;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
0_isize
|
||||
}
|
||||
|
||||
fn stardict_strcmp(s1: &str, s2: &str) -> isize {
|
||||
/*
|
||||
#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
#define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
|
||||
gint
|
||||
g_ascii_strcasecmp (const gchar *s1,
|
||||
const gchar *s2)
|
||||
{
|
||||
gint c1, c2;
|
||||
|
||||
g_return_val_if_fail (s1 != NULL, 0);
|
||||
g_return_val_if_fail (s2 != NULL, 0);
|
||||
|
||||
while (*s1 && *s2)
|
||||
{
|
||||
c1 = (gint)(guchar) TOLOWER (*s1);
|
||||
c2 = (gint)(guchar) TOLOWER (*s2);
|
||||
if (c1 != c2)
|
||||
return (c1 - c2);
|
||||
s1++; s2++;
|
||||
}
|
||||
|
||||
return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
|
||||
}
|
||||
|
||||
const gint a = g_ascii_strcasecmp(s1, s2);
|
||||
if (a == 0)
|
||||
return strcmp(s1, s2);
|
||||
else
|
||||
return a;
|
||||
*/
|
||||
let res = g_ascii_strcasecmp(s1, s2);
|
||||
if res == 0 {
|
||||
assert_eq!(s1.len(), s2.len());
|
||||
for it in s1.bytes().zip(s2.bytes()) {
|
||||
let (b1, b2) = it;
|
||||
if b1 != b2 {
|
||||
return (b1 as isize) - (b2 as isize);
|
||||
}
|
||||
}
|
||||
0_isize
|
||||
} else {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
fn stardict_str_order(s1: &str, s2: &str) -> Ordering {
|
||||
let cmp_res = stardict_strcmp(s1, s2);
|
||||
if cmp_res < 0 {
|
||||
Ordering::Less
|
||||
} else if cmp_res > 0 {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
fn get_key_by_offset(content: &[u8], key_pos: usize) -> (&str, u64, usize) {
|
||||
let key = &content[key_pos..];
|
||||
let end_of_key = key.iter().position(|&x| x == b'\0').unwrap() + key_pos;
|
||||
let mut reader = Cursor::new(&content[end_of_key + 1..]);
|
||||
let offset = reader.read_u32::<NetworkEndian>().unwrap() as u64;
|
||||
let length = reader.read_u32::<NetworkEndian>().unwrap() as usize;
|
||||
(from_utf8(&content[key_pos..end_of_key]).unwrap(), offset, length)
|
||||
}
|
||||
|
||||
impl DictionaryIndex for MemoryDictionaryIndex {
|
||||
fn get_key(&self, idx: usize) -> (&str, u64, usize) {
|
||||
let key_pos = self.wordlist[idx];
|
||||
get_key_by_offset(&self.idx_content, key_pos)
|
||||
/*
|
||||
let key = &self.idx_content[key_pos..];
|
||||
let end_of_key = key.iter().position(|&x| x == b'\0').unwrap();
|
||||
let mut reader = Cursor::new(&self.idx_content[end_of_key + 1..]);
|
||||
let offset = reader.read_u32::<NetworkEndian>().unwrap() as u64;
|
||||
let length = reader.read_u32::<NetworkEndian>().unwrap() as usize;
|
||||
(from_utf8(&self.idx_content[key_pos..(key_pos + end_of_key)]).unwrap(), offset, length)*/
|
||||
}
|
||||
fn count(&self) -> usize {
|
||||
self.wordlist.len()
|
||||
}
|
||||
fn find(&self, key: &str) -> Result<usize, usize> {
|
||||
self.wordlist.binary_search_by(
|
||||
|probe| stardict_str_order(get_key_by_offset(&self.idx_content, *probe).0, key)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_offsets_of_phrases_in_index(expected_wordcount: usize, idx_content: &[u8]) -> Result<Vec<usize>, String> {
|
||||
const PADDING_LENGTH: usize = 8;
|
||||
let mut wordlist = vec![];
|
||||
wordlist.reserve(expected_wordcount);
|
||||
{
|
||||
let mut slice = idx_content;
|
||||
let mut pos : usize = 0;
|
||||
while let Some(idx) = slice.iter().position(|&x| x == b'\0') {
|
||||
let (head, tail) = slice.split_at(idx);
|
||||
try!(from_utf8(head).map_err(|err| "invalid utf-8 in key".to_string()));
|
||||
wordlist.push(pos);
|
||||
pos += head.len() + PADDING_LENGTH + 1;
|
||||
// +1 to skip over the NUL
|
||||
if tail.len() > PADDING_LENGTH + 1 {
|
||||
slice = &tail[PADDING_LENGTH + 1..];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if wordlist.len() != expected_wordcount {
|
||||
Result::Err(format!("Expect words in index {}, got {} words", expected_wordcount, wordlist.len()))
|
||||
} else {
|
||||
Result::Ok(wordlist)
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryDictionaryIndex {
|
||||
pub fn new_from_vec(expected_wordcount: usize, idx_content: Vec<u8>) -> Result<MemoryDictionaryIndex, String> {
|
||||
let wordlist = try!(get_offsets_of_phrases_in_index(expected_wordcount, idx_content.as_slice()));
|
||||
Result::Ok(MemoryDictionaryIndex {idx_content: idx_content, wordlist: wordlist})
|
||||
}
|
||||
|
||||
pub fn new_from_gzip(expected_wordcount: usize, idx_gz_file_path: &Path) -> Result<MemoryDictionaryIndex, String> {
|
||||
let mut idx_file = try!(File::open(idx_gz_file_path).map_err(|err| err.description().to_string()));
|
||||
let mut gzip_decoder = try!(GzDecoder::new(idx_file).map_err(|err| err.description().to_string()));
|
||||
let mut idx_content = Vec::<u8>::new();
|
||||
if let Result::Err(err) = gzip_decoder.read_to_end(&mut idx_content) {
|
||||
return Result::Err(format!("Can not read index file: {}", err.description()));
|
||||
}
|
||||
let wordlist = try!(get_offsets_of_phrases_in_index(expected_wordcount, idx_content.as_slice()));
|
||||
Result::Ok(MemoryDictionaryIndex {idx_content: idx_content, wordlist: wordlist})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiskDictionaryIndex {
|
||||
file_map: MemMappedFile,
|
||||
wordlist: Vec<usize>,
|
||||
}
|
||||
|
||||
impl DictionaryIndex for DiskDictionaryIndex {
|
||||
fn get_key(&self, idx: usize) -> (&str, u64, usize) {
|
||||
let key_pos = self.wordlist[idx];
|
||||
let idx_content = self.file_map.get_chunk(0, self.file_map.len()).unwrap();
|
||||
get_key_by_offset(idx_content, key_pos)
|
||||
}
|
||||
fn count(&self) -> usize { self.wordlist.len() }
|
||||
|
||||
fn find(&self, key: &str) -> Result<usize, usize> {
|
||||
let idx_content = self.file_map.get_chunk(0, self.file_map.len()).unwrap();
|
||||
self.wordlist.binary_search_by(
|
||||
|probe| stardict_str_order(get_key_by_offset(idx_content, *probe).0, key)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl DiskDictionaryIndex {
|
||||
pub fn new(expected_wordcount: usize, idx_file_path: &Path) -> Result<DiskDictionaryIndex, String> {
|
||||
let file_map = try!(MemMappedFile::new(idx_file_path));
|
||||
let whole_map = try!(file_map.get_chunk(0, file_map.len()));
|
||||
let wordlist = try!(get_offsets_of_phrases_in_index(expected_wordcount, whole_map));
|
||||
Ok(DiskDictionaryIndex{file_map: file_map, wordlist: wordlist})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use super::stardict_str_order;
|
||||
use super::stardict_strcmp;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::BufReader;
|
||||
use std::io::BufRead;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn index_memory_open() {
|
||||
let idx_file_name = Path::new("tests/stardict-test_dict-2.4.2/test_dict.idx");
|
||||
let mut file = File::open(idx_file_name).unwrap();
|
||||
let mut idx_content = Vec::<u8>::new();
|
||||
file.read_to_end(&mut idx_content).unwrap();
|
||||
let mut index = MemoryDictionaryIndex::new_from_vec(1, idx_content).unwrap();
|
||||
assert_eq!(1_usize, index.count());
|
||||
assert_eq!("test", index.get_key(0).0);
|
||||
|
||||
let idx_file_name = Path::new("tests/words_dic/stardict-words-2.4.2/words.idx");
|
||||
let mut file = File::open(idx_file_name).unwrap();
|
||||
let mut idx_content = Vec::<u8>::new();
|
||||
file.read_to_end(&mut idx_content).unwrap();
|
||||
let index_size = 1671704_usize;
|
||||
let mut mem_index = MemoryDictionaryIndex::new_from_vec(index_size, idx_content).unwrap();
|
||||
assert_eq!(index_size, mem_index.count());
|
||||
let mut disk_index = DiskDictionaryIndex::new(index_size, idx_file_name).unwrap();
|
||||
assert_eq!(index_size, disk_index.count());
|
||||
let mut gz_mem_index = MemoryDictionaryIndex::new_from_gzip(index_size,
|
||||
Path::new("tests/words_dic/stardict-words-2.4.2/words.idx.gz")).unwrap();
|
||||
assert_eq!(index_size, gz_mem_index.count());
|
||||
{
|
||||
let mut counter: usize = 0;
|
||||
let f = File::open("tests/words_dic/words.dummy").unwrap();
|
||||
let mut file = BufReader::new(&f);
|
||||
let mut dic_words = HashSet::new();
|
||||
for line in file.lines() {
|
||||
let l = line.unwrap();
|
||||
dic_words.insert(l);
|
||||
}
|
||||
for i in 0..index.count() {
|
||||
for index in [&mem_index as &DictionaryIndex, &disk_index as &DictionaryIndex, &gz_mem_index as &DictionaryIndex].iter() {
|
||||
let (key, _, _) = index.get_key(i);
|
||||
if !dic_words.contains(key) {
|
||||
panic!("no '{}'(len {}) idx {} in dic_words", key, key.len(), i);
|
||||
}
|
||||
match index.find(key) {
|
||||
Err(idx) => panic!("we search '{}', and not found err({})", key, idx),
|
||||
Ok(idx) => assert_eq!(idx, i),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_stardict_strcmp_small() {
|
||||
let arr_s = ["a", "b", "c", "d", "z"];
|
||||
let seek = "c";
|
||||
assert_eq!(arr_s.binary_search_by(|probe| stardict_str_order(probe, seek)), Ok(2));
|
||||
let seek = "e";
|
||||
assert_eq!(arr_s.binary_search_by(|probe| stardict_str_order(probe, seek)), Err(4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_stardict_strcmp_big() {
|
||||
let mut exp_res_list = vec![];
|
||||
{
|
||||
let f = File::open("tests/stardict_strcmp_test_data_cmp_exp.txt").unwrap();
|
||||
let mut file = BufReader::new(&f);
|
||||
for line in file.lines() {
|
||||
let line = line.unwrap();
|
||||
let exp_res = line.parse::<isize>().unwrap();
|
||||
exp_res_list.push(exp_res);
|
||||
}
|
||||
}
|
||||
|
||||
let f = File::open("tests/stardict_strcmp_test_data.txt").unwrap();
|
||||
let mut file = BufReader::new(&f);
|
||||
let mut prev_line : String = "".to_string();
|
||||
let mut counter : u8 = 0;
|
||||
let mut exp_it = exp_res_list.iter();
|
||||
for line in file.lines() {
|
||||
if counter == 1 {
|
||||
let cur_line = line.unwrap();
|
||||
let res = stardict_strcmp(&prev_line, &cur_line);
|
||||
let exp_res = exp_it.next().unwrap();
|
||||
if res != *exp_res {
|
||||
panic!("we expect {}, got {} for '{}' vs '{}'", exp_res, res, prev_line, cur_line);
|
||||
}
|
||||
} else {
|
||||
prev_line = line.unwrap();
|
||||
}
|
||||
counter = (counter + 1) % 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@@ -142,8 +142,10 @@ static std::string parse_data(const gchar *data, bool colorize_output)
|
||||
p += sizeof(guint32);
|
||||
while (guint32(p - data) < data_size) {
|
||||
switch (*p++) {
|
||||
case 'm':
|
||||
case 'l': //need more work...
|
||||
case 'h': // HTML data
|
||||
case 'w': // WikiMedia markup data
|
||||
case 'm': // plain text, utf-8
|
||||
case 'l': // not utf-8, some other locale encoding, discouraged, need more work...
|
||||
sec_size = strlen(p);
|
||||
if (sec_size) {
|
||||
res += "\n";
|
||||
@@ -153,8 +155,8 @@ static std::string parse_data(const gchar *data, bool colorize_output)
|
||||
}
|
||||
sec_size++;
|
||||
break;
|
||||
case 'g':
|
||||
case 'x':
|
||||
case 'g': // pango markup data
|
||||
case 'x': // xdxf
|
||||
sec_size = strlen(p);
|
||||
if (sec_size) {
|
||||
res += "\n";
|
||||
@@ -164,7 +166,7 @@ static std::string parse_data(const gchar *data, bool colorize_output)
|
||||
}
|
||||
sec_size++;
|
||||
break;
|
||||
case 't':
|
||||
case 't': // english phonetic string
|
||||
sec_size = strlen(p);
|
||||
if (sec_size) {
|
||||
res += "\n";
|
||||
@@ -176,15 +178,15 @@ static std::string parse_data(const gchar *data, bool colorize_output)
|
||||
}
|
||||
sec_size++;
|
||||
break;
|
||||
case 'k':
|
||||
case 'y':
|
||||
case 'k': // KingSoft PowerWord data
|
||||
case 'y': // chinese YinBiao or japanese kana, utf-8
|
||||
sec_size = strlen(p);
|
||||
if (sec_size)
|
||||
res += std::string(p, sec_size);
|
||||
sec_size++;
|
||||
break;
|
||||
case 'W':
|
||||
case 'P':
|
||||
case 'W': // wav file
|
||||
case 'P': // picture data
|
||||
sec_size = get_uint32(p);
|
||||
sec_size += sizeof(guint32);
|
||||
break;
|
||||
@@ -192,7 +194,6 @@ static std::string parse_data(const gchar *data, bool colorize_output)
|
||||
p += sec_size;
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -248,7 +249,7 @@ void Library::LookupData(const std::string &str, TSearchResultList& res_list)
|
||||
}
|
||||
}
|
||||
|
||||
void Library::print_search_result(FILE *out, const TSearchResult & res)
|
||||
void Library::print_search_result(FILE *out, const TSearchResult &res, bool &first_result)
|
||||
{
|
||||
std::string loc_bookname, loc_def, loc_exp;
|
||||
|
||||
@@ -257,7 +258,18 @@ void Library::print_search_result(FILE *out, const TSearchResult & res)
|
||||
loc_def = utf8_to_locale_ign_err(res.def);
|
||||
loc_exp = utf8_to_locale_ign_err(res.exp);
|
||||
}
|
||||
if (json_) {
|
||||
if (!first_result) {
|
||||
fputs(",", out);
|
||||
} else {
|
||||
first_result = false;
|
||||
}
|
||||
fprintf(out, "{\"dict\": \"%s\",\"word\":\"%s\",\"definition\":\"%s\"}",
|
||||
json_escape_string(res.bookname).c_str(),
|
||||
json_escape_string(res.def).c_str(),
|
||||
json_escape_string(res.exp).c_str());
|
||||
|
||||
} else {
|
||||
fprintf(out,
|
||||
"-->%s%s%s\n"
|
||||
"-->%s%s%s\n"
|
||||
@@ -270,14 +282,19 @@ void Library::print_search_result(FILE *out, const TSearchResult & res)
|
||||
colorize_output_ ? ESC_END : "",
|
||||
utf8_output_ ? res.exp.c_str() : loc_exp.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class sdcv_pager {
|
||||
namespace
|
||||
{
|
||||
class sdcv_pager final
|
||||
{
|
||||
public:
|
||||
sdcv_pager(bool ignore_env = false) {
|
||||
explicit sdcv_pager(bool ignore_env = false)
|
||||
{
|
||||
output = stdout;
|
||||
if (ignore_env)
|
||||
if (ignore_env) {
|
||||
return;
|
||||
}
|
||||
const gchar *pager = g_getenv("SDCV_PAGER");
|
||||
if (pager && (output = popen(pager, "w")) == nullptr) {
|
||||
perror(_("popen failed"));
|
||||
@@ -286,11 +303,14 @@ namespace {
|
||||
}
|
||||
sdcv_pager(const sdcv_pager &) = delete;
|
||||
sdcv_pager &operator=(const sdcv_pager &) = delete;
|
||||
~sdcv_pager() {
|
||||
if (output != stdout)
|
||||
fclose(output);
|
||||
~sdcv_pager()
|
||||
{
|
||||
if (output != stdout) {
|
||||
pclose(output);
|
||||
}
|
||||
}
|
||||
FILE *get_stream() { return output; }
|
||||
|
||||
private:
|
||||
FILE *output;
|
||||
};
|
||||
@@ -336,7 +356,7 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
|
||||
break;
|
||||
case qtSIMPLE:
|
||||
SimpleLookup(get_impl(str), res_list);
|
||||
if (res_list.empty())
|
||||
if (res_list.empty() && fuzzy_)
|
||||
LookupWithFuzzy(get_impl(str), res_list);
|
||||
break;
|
||||
case qtDATA:
|
||||
@@ -346,6 +366,10 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
|
||||
/*nothing*/;
|
||||
}
|
||||
|
||||
bool first_result = true;
|
||||
if (json_) {
|
||||
fputc('[', stdout);
|
||||
}
|
||||
if (!res_list.empty()) {
|
||||
/* try to be more clever, if there are
|
||||
one or zero results per dictionary show all
|
||||
@@ -370,8 +394,10 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
|
||||
} //if (!force)
|
||||
|
||||
if (!show_all_results && !force) {
|
||||
if (!json_) {
|
||||
printf(_("Found %zu items, similar to %s.\n"), res_list.size(),
|
||||
utf8_output_ ? get_impl(str) : utf8_to_locale_ign_err(get_impl(str)).c_str());
|
||||
}
|
||||
for (size_t i = 0; i < res_list.size(); ++i) {
|
||||
const std::string loc_bookname = utf8_to_locale_ign_err(res_list[i].bookname);
|
||||
const std::string loc_def = utf8_to_locale_ign_err(res_list[i].def);
|
||||
@@ -392,7 +418,7 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
|
||||
if (choise >= 0 && choise < int(res_list.size())) {
|
||||
sdcv_pager pager;
|
||||
io.add_to_history(res_list[choise].def.c_str());
|
||||
print_search_result(pager.get_stream(), res_list[choise]);
|
||||
print_search_result(pager.get_stream(), res_list[choise], first_result);
|
||||
break;
|
||||
} else if (choise == -1) {
|
||||
break;
|
||||
@@ -401,20 +427,26 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
|
||||
res_list.size() - 1);
|
||||
}
|
||||
} else {
|
||||
sdcv_pager pager(force);
|
||||
sdcv_pager pager(force || json_);
|
||||
if (!json_) {
|
||||
fprintf(pager.get_stream(), _("Found %zu items, similar to %s.\n"),
|
||||
res_list.size(), utf8_output_ ? get_impl(str) : utf8_to_locale_ign_err(get_impl(str)).c_str());
|
||||
for (const TSearchResult& search_res : res_list)
|
||||
print_search_result(pager.get_stream(), search_res);
|
||||
}
|
||||
for (const TSearchResult &search_res : res_list) {
|
||||
print_search_result(pager.get_stream(), search_res, first_result);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
std::string loc_str;
|
||||
if (!utf8_output_)
|
||||
loc_str = utf8_to_locale_ign_err(get_impl(str));
|
||||
|
||||
if (!json_)
|
||||
printf(_("Nothing similar to %s, sorry :(\n"), utf8_output_ ? get_impl(str) : loc_str.c_str());
|
||||
}
|
||||
|
||||
if (json_) {
|
||||
fputs("]\n", stdout);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "stardict_lib.hpp"
|
||||
#include "readline.hpp"
|
||||
#include "stardict_lib.hpp"
|
||||
|
||||
//this structure is wrapper and it need for unification
|
||||
//results of search whith return Dicts class
|
||||
@@ -14,7 +14,9 @@ struct TSearchResult {
|
||||
std::string exp;
|
||||
|
||||
TSearchResult(const std::string &bookname_, const std::string &def_, const std::string &exp_)
|
||||
: bookname(bookname_), def(def_), exp(exp_)
|
||||
: bookname(bookname_)
|
||||
, def(def_)
|
||||
, exp(exp_)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -23,21 +25,30 @@ typedef std::vector<TSearchResult> TSearchResultList;
|
||||
|
||||
//this class is wrapper around Dicts class for easy use
|
||||
//of it
|
||||
class Library : public Libs {
|
||||
class Library : public Libs
|
||||
{
|
||||
public:
|
||||
Library(bool uinput, bool uoutput, bool colorize_output):
|
||||
utf8_input_(uinput), utf8_output_(uoutput), colorize_output_(colorize_output) {}
|
||||
Library(bool uinput, bool uoutput, bool colorize_output, bool use_json, bool no_fuzzy)
|
||||
: utf8_input_(uinput)
|
||||
, utf8_output_(uoutput)
|
||||
, colorize_output_(colorize_output)
|
||||
, json_(use_json)
|
||||
{
|
||||
setVerbose(!use_json);
|
||||
setFuzzy(!no_fuzzy);
|
||||
}
|
||||
|
||||
bool process_phrase(const char *loc_str, IReadLine &io, bool force = false);
|
||||
|
||||
private:
|
||||
bool utf8_input_;
|
||||
bool utf8_output_;
|
||||
bool colorize_output_;
|
||||
bool json_;
|
||||
|
||||
void SimpleLookup(const std::string &str, TSearchResultList &res_list);
|
||||
void LookupWithFuzzy(const std::string &str, TSearchResultList &res_list);
|
||||
void LookupWithRule(const std::string &str, TSearchResultList &res_lsit);
|
||||
void LookupData(const std::string &str, TSearchResultList &res_list);
|
||||
void print_search_result(FILE *out, const TSearchResult & res);
|
||||
void print_search_result(FILE *out, const TSearchResult &res, bool &first_result);
|
||||
};
|
||||
|
||||
|
||||
67
src/main.rs
67
src/main.rs
@@ -1,67 +0,0 @@
|
||||
extern crate getopts;
|
||||
extern crate gettext;
|
||||
extern crate ini;
|
||||
extern crate byteorder;
|
||||
extern crate libc;
|
||||
extern crate flate2;
|
||||
|
||||
mod core;
|
||||
mod index;
|
||||
mod data;
|
||||
mod mem_mapped_file;
|
||||
use core::Dictionary;
|
||||
|
||||
use std::env;
|
||||
use std::result::Result;
|
||||
use getopts::Options;
|
||||
use gettext::Catalog;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
struct Library {
|
||||
dicts : Vec<Dictionary>
|
||||
}
|
||||
|
||||
impl Library {
|
||||
fn new(dict_dirs: &[&Path], dict_order_names: &[String], dict_disable_names: &[String]) -> Result<Library, String> {
|
||||
let dicts = vec![Dictionary::new(Path::new("/home/evgeniy/.stardict/dic/stardict-Mueller7accentGPL-2.4.2/Mueller7accentGPL.ifo")).unwrap()];
|
||||
Ok(Library{dicts: dicts})
|
||||
}
|
||||
|
||||
pub fn simple_lookup(&mut self, phrase: &str) /*-> Option<String>*/ {
|
||||
for dict in self.dicts.iter_mut() {
|
||||
if let Some(translation) = dict.find(phrase) {
|
||||
println!("{}", translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_usage(program: &str, opts: Options) {
|
||||
let brief = format!("Usage: {} [options] [list of words]", program);
|
||||
print!("{}", opts.usage(&brief));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let translation_f = File::open("/usr/share/locale/ru/LC_MESSAGES/sdcv.mo").expect("could not open the catalog");
|
||||
let catalog = Catalog::parse(translation_f).expect("could not parse the catalog");
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let program = args[0].clone();
|
||||
let mut opts = Options::new();
|
||||
opts.optflag("v", "version", catalog.gettext("display version information and exit"));
|
||||
opts.optflag("h", "help", catalog.gettext("Show help options"));
|
||||
let matches = match opts.parse(&args[1..]) {
|
||||
Ok(m) => { m }
|
||||
Err(f) => { panic!(f.to_string()) }
|
||||
};
|
||||
if matches.opt_present("h") {
|
||||
print_usage(&program, opts);
|
||||
return;
|
||||
}
|
||||
let dict_dirs = vec![Path::new("/tmp")];
|
||||
let dict_order_names: Vec<String> = vec![];
|
||||
let dict_disable_names: Vec<String> = vec![];
|
||||
let mut library = Library::new(&dict_dirs, &dict_order_names, &dict_disable_names).unwrap();
|
||||
library.simple_lookup("man");
|
||||
}
|
||||
@@ -5,16 +5,17 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
# include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <glib.h>
|
||||
|
||||
class MapFile {
|
||||
class MapFile
|
||||
{
|
||||
public:
|
||||
MapFile() {}
|
||||
~MapFile();
|
||||
@@ -22,6 +23,7 @@ public:
|
||||
MapFile &operator=(const MapFile &) = delete;
|
||||
bool open(const char *file_name, unsigned long file_size);
|
||||
gchar *begin() { return data; }
|
||||
|
||||
private:
|
||||
char *data = nullptr;
|
||||
unsigned long size = 0ul;
|
||||
@@ -82,4 +84,3 @@ inline MapFile::~MapFile()
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
use libc::{c_void, c_int};
|
||||
use libc;
|
||||
|
||||
pub struct MemMappedFile {
|
||||
mem_addr: *const u8,
|
||||
length: usize,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl MemMappedFile {
|
||||
pub fn new(file_name: &Path) -> Result<MemMappedFile, String> {
|
||||
let file = try!(File::open(file_name).map_err(|err| err.to_string()));
|
||||
let metadata = try!(file.metadata().map_err(|err| err.to_string()));
|
||||
if !metadata.is_file() {
|
||||
return Err(format!("{} is not file", file_name.to_str().unwrap()));
|
||||
}
|
||||
let file_len = metadata.len();
|
||||
let fd = file.as_raw_fd();
|
||||
let addr: *const u8 = ptr::null();
|
||||
let res = unsafe {
|
||||
libc::mmap(addr as *mut c_void, file_len as libc::size_t, libc::PROT_READ, libc::MAP_SHARED,
|
||||
fd, 0)
|
||||
};
|
||||
if res == libc::MAP_FAILED {
|
||||
Err(format!("mmap for {} failed", file_name.to_str().unwrap()))
|
||||
} else {
|
||||
Ok(MemMappedFile{mem_addr: res as *mut u8, length: file_len as usize})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize { self.length }
|
||||
|
||||
pub fn get_chunk<'a>(&self, offset: usize, size: usize) -> Result<&'a[u8], String> {
|
||||
let end = offset + size;
|
||||
if end > self.length {
|
||||
return Err(format!("offset out of range from 0 to {}", self.length));
|
||||
}
|
||||
Ok(unsafe {slice::from_raw_parts(self.mem_addr.offset(offset as isize), size) })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl Drop for MemMappedFile {
|
||||
fn drop(&mut self) {
|
||||
let res: c_int = unsafe {
|
||||
// `munmap` only panics due to logic errors
|
||||
libc::munmap(self.mem_addr as *mut c_void, self.length as libc::size_t)
|
||||
};
|
||||
if res == -1 {
|
||||
panic!("munmap return error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use std::path::Path;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
|
||||
static CRCTAB: [u32; 256] = [
|
||||
0x00000000,
|
||||
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
||||
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
|
||||
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
|
||||
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
|
||||
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
|
||||
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
|
||||
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
|
||||
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
|
||||
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
|
||||
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
|
||||
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
|
||||
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
|
||||
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
|
||||
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
|
||||
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
|
||||
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
|
||||
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
|
||||
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
|
||||
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
|
||||
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
|
||||
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
|
||||
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
|
||||
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
|
||||
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
|
||||
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
|
||||
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
|
||||
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
|
||||
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
|
||||
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
|
||||
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
|
||||
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
|
||||
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
|
||||
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
|
||||
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
];
|
||||
|
||||
fn crc32(buf: &[u32]) -> u32 {
|
||||
let mut crc = 0_u32;
|
||||
for item in buf {
|
||||
let mut byte: u32 = item & 0xFF_u32;
|
||||
crc = (crc << 8) ^ CRCTAB[(((crc >> 24) ^ byte) & 0xFF) as usize];
|
||||
|
||||
byte = (item >> 8) & 0xFF_u32;
|
||||
crc = (crc << 8) ^ CRCTAB[(((crc >> 24) ^ byte) & 0xFF) as usize];
|
||||
|
||||
byte = (item >> 16) & 0xFF_u32;
|
||||
crc = (crc << 8) ^ CRCTAB[(((crc >> 24) ^ byte) & 0xFF) as usize];
|
||||
|
||||
byte = (item >> 24) & 0xFF_u32;
|
||||
crc = (crc << 8) ^ CRCTAB[(((crc >> 24) ^ byte) & 0xFF) as usize];
|
||||
}
|
||||
!crc & 0xFFFFFFFF_u32
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn mem_mapped_file_basic_test() {
|
||||
let mfile = MemMappedFile::new(Path::new("tests/words_dic/stardict-words-2.4.2/words.idx")).unwrap();
|
||||
let mem_chunk = mfile.get_chunk(0, 16).unwrap();
|
||||
assert_eq!(mem_chunk.len(), 16);
|
||||
let exp : Vec<u8> = vec![0x21, 0, 0, 0, 0, 0, 0, 0, 0, 0xa, 0x21, 0x20, 0x23, 0x24, 0x25, 0x5e];
|
||||
assert_eq!(mem_chunk, exp.as_slice());
|
||||
|
||||
const CHUNK_SIZE: usize = 256;
|
||||
let n_chunks = (mfile.len() + CHUNK_SIZE -1) / CHUNK_SIZE;
|
||||
let mut data: Vec<u32> = Vec::with_capacity(mfile.len() / 4);
|
||||
for i in 0..(n_chunks - 1) {
|
||||
let mem_chunk = mfile.get_chunk(i * CHUNK_SIZE, CHUNK_SIZE).unwrap();
|
||||
let data_bytes = &mem_chunk[0] as *const u8;
|
||||
let data_words: *const u32 = unsafe { mem::transmute(data_bytes) };
|
||||
let chunk_u32_view = unsafe { slice::from_raw_parts(data_words, CHUNK_SIZE / 4) };
|
||||
data.extend_from_slice(chunk_u32_view);
|
||||
}
|
||||
let res_crc = crc32(data.as_slice());
|
||||
assert_eq!(res_crc, 0x2a04c834_u32);
|
||||
let rest = mfile.len() - (n_chunks - 1) * CHUNK_SIZE;
|
||||
if rest > 0 {
|
||||
let mem_chunk = mfile.get_chunk((n_chunks - 1) * CHUNK_SIZE, rest).unwrap();
|
||||
let add_size = (rest + 3) / 4;
|
||||
for i in 0..add_size {
|
||||
let mut word = 0_u32;
|
||||
for j in 0..4 {
|
||||
if i * 4 + j < mem_chunk.len() {
|
||||
word |= (mem_chunk[i * 4 + j] as u32) << (j * 8);
|
||||
}
|
||||
}
|
||||
data.push(word);
|
||||
}
|
||||
}
|
||||
let res_crc = crc32(data.as_slice());
|
||||
assert_eq!(res_crc, 0x6ae491df);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@@ -25,8 +25,8 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#ifdef WITH_READLINE
|
||||
# include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
#include <glib.h>
|
||||
|
||||
@@ -34,10 +34,9 @@
|
||||
|
||||
#include "readline.hpp"
|
||||
|
||||
#ifndef WITH_READLINE
|
||||
namespace {
|
||||
static bool stdio_getline(FILE *in, std::string & str)
|
||||
bool stdio_getline(FILE *in, std::string &str)
|
||||
{
|
||||
assert(in != nullptr);
|
||||
str.clear();
|
||||
int ch;
|
||||
while ((ch = fgetc(in)) != EOF && ch != '\n')
|
||||
@@ -46,9 +45,14 @@ namespace {
|
||||
return EOF != ch;
|
||||
}
|
||||
|
||||
class dummy_readline : public IReadLine {
|
||||
#ifndef WITH_READLINE
|
||||
namespace
|
||||
{
|
||||
class dummy_readline : public IReadLine
|
||||
{
|
||||
public:
|
||||
bool read(const string& banner, string& line) override {
|
||||
bool read(const std::string &banner, std::string &line) override
|
||||
{
|
||||
printf("%s", banner.c_str());
|
||||
return stdio_getline(stdin, line);
|
||||
}
|
||||
@@ -56,18 +60,22 @@ namespace {
|
||||
}
|
||||
#else
|
||||
|
||||
namespace {
|
||||
class real_readline : public IReadLine {
|
||||
namespace
|
||||
{
|
||||
class real_readline : public IReadLine
|
||||
{
|
||||
|
||||
public:
|
||||
real_readline() {
|
||||
real_readline()
|
||||
{
|
||||
rl_readline_name = "sdcv";
|
||||
using_history();
|
||||
const std::string histname = std::string(g_get_home_dir()) + G_DIR_SEPARATOR + ".sdcv_history";
|
||||
read_history(histname.c_str());
|
||||
}
|
||||
|
||||
~real_readline() {
|
||||
~real_readline()
|
||||
{
|
||||
const std::string histname = std::string(g_get_home_dir()) + G_DIR_SEPARATOR + ".sdcv_history";
|
||||
write_history(histname.c_str());
|
||||
const gchar *hist_size_str = g_getenv("SDCV_HISTSIZE");
|
||||
@@ -77,7 +85,8 @@ namespace {
|
||||
history_truncate_file(histname.c_str(), hist_size);
|
||||
}
|
||||
|
||||
bool read(const std::string &banner, std::string& line) override {
|
||||
bool read(const std::string &banner, std::string &line) override
|
||||
{
|
||||
char *phrase = nullptr;
|
||||
phrase = readline(banner.c_str());
|
||||
if (phrase) {
|
||||
@@ -88,7 +97,8 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_to_history(const std::string& phrase) override {
|
||||
void add_to_history(const std::string &phrase) override
|
||||
{
|
||||
add_history(phrase.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
class IReadLine {
|
||||
class IReadLine
|
||||
{
|
||||
public:
|
||||
virtual ~IReadLine() {}
|
||||
virtual bool read(const std::string &banner, std::string &line) = 0;
|
||||
@@ -11,4 +12,4 @@ public:
|
||||
|
||||
extern std::string sdcv_readline;
|
||||
extern IReadLine *create_readline_object();
|
||||
|
||||
extern bool stdio_getline(FILE *in, std::string &str);
|
||||
|
||||
128
src/sdcv.cpp
128
src/sdcv.cpp
@@ -15,18 +15,20 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <clocale>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -54,9 +56,11 @@ static void free_str_array(gchar **arr)
|
||||
}
|
||||
namespace glib
|
||||
{
|
||||
typedef ResourceWrapper<gchar *, gchar *, free_str_array> StrArr;
|
||||
using StrArr = ResourceWrapper<gchar *, gchar *, free_str_array>;
|
||||
}
|
||||
|
||||
static void list_dicts(const std::list<std::string> &dicts_dir_list, bool use_json);
|
||||
|
||||
int main(int argc, char *argv[]) try {
|
||||
setlocale(LC_ALL, "");
|
||||
#if ENABLE_NLS
|
||||
@@ -71,9 +75,12 @@ int main(int argc, char *argv[]) try {
|
||||
gboolean show_list_dicts = FALSE;
|
||||
glib::StrArr use_dict_list;
|
||||
gboolean non_interactive = FALSE;
|
||||
gboolean json_output = FALSE;
|
||||
gboolean no_fuzzy = FALSE;
|
||||
gboolean utf8_output = FALSE;
|
||||
gboolean utf8_input = FALSE;
|
||||
glib::CharStr opt_data_dir;
|
||||
gboolean only_data_dir = FALSE;
|
||||
gboolean colorize = FALSE;
|
||||
|
||||
const GOptionEntry entries[] = {
|
||||
@@ -86,6 +93,10 @@ int main(int argc, char *argv[]) try {
|
||||
_("bookname") },
|
||||
{ "non-interactive", 'n', 0, G_OPTION_ARG_NONE, &non_interactive,
|
||||
_("for use in scripts"), nullptr },
|
||||
{ "json-output", 'j', 0, G_OPTION_ARG_NONE, &json_output,
|
||||
_("print the result formatted as JSON"), nullptr },
|
||||
{ "exact-search", 'e', 0, G_OPTION_ARG_NONE, &no_fuzzy,
|
||||
_("do not fuzzy-search for similar words, only return exact matches"), nullptr },
|
||||
{ "utf8-output", '0', 0, G_OPTION_ARG_NONE, &utf8_output,
|
||||
_("output must be in utf8"), nullptr },
|
||||
{ "utf8-input", '1', 0, G_OPTION_ARG_NONE, &utf8_input,
|
||||
@@ -93,9 +104,11 @@ int main(int argc, char *argv[]) try {
|
||||
{ "data-dir", '2', 0, G_OPTION_ARG_STRING, get_addr(opt_data_dir),
|
||||
_("use this directory as path to stardict data directory"),
|
||||
_("path/to/dir") },
|
||||
{ "only-data-dir", 'x', 0, G_OPTION_ARG_NONE, &only_data_dir,
|
||||
_("only use the dictionaries in data-dir, do not search in user and system directories"), nullptr },
|
||||
{ "color", 'c', 0, G_OPTION_ARG_NONE, &colorize,
|
||||
_("colorize the output"), nullptr },
|
||||
{ nullptr },
|
||||
{},
|
||||
};
|
||||
|
||||
glib::Error error;
|
||||
@@ -118,10 +131,12 @@ int main(int argc, char *argv[]) try {
|
||||
const gchar *stardict_data_dir = g_getenv("STARDICT_DATA_DIR");
|
||||
std::string data_dir;
|
||||
if (!opt_data_dir) {
|
||||
if (!only_data_dir) {
|
||||
if (stardict_data_dir)
|
||||
data_dir = stardict_data_dir;
|
||||
else
|
||||
data_dir = "/usr/share/stardict/dic";
|
||||
}
|
||||
} else {
|
||||
data_dir = get_impl(opt_data_dir);
|
||||
}
|
||||
@@ -130,58 +145,72 @@ int main(int argc, char *argv[]) try {
|
||||
if (!homedir)
|
||||
homedir = g_get_home_dir();
|
||||
|
||||
const std::list<std::string> dicts_dir_list = {
|
||||
std::string(homedir) + G_DIR_SEPARATOR + ".stardict" + G_DIR_SEPARATOR + "dic",
|
||||
data_dir
|
||||
};
|
||||
|
||||
std::list<std::string> dicts_dir_list;
|
||||
if (!only_data_dir)
|
||||
dicts_dir_list.push_back(std::string(homedir) + G_DIR_SEPARATOR + ".stardict" + G_DIR_SEPARATOR + "dic");
|
||||
dicts_dir_list.push_back(data_dir);
|
||||
if (show_list_dicts) {
|
||||
printf(_("Dictionary's name Word count\n"));
|
||||
std::list<std::string> order_list, disable_list;
|
||||
for_each_file(dicts_dir_list, ".ifo", order_list,
|
||||
disable_list, [](const std::string &filename, bool) -> void {
|
||||
DictInfo dict_info;
|
||||
if (dict_info.load_from_ifo_file(filename, false)) {
|
||||
const std::string bookname = utf8_to_locale_ign_err(dict_info.bookname);
|
||||
printf("%s %d\n", bookname.c_str(), dict_info.wordcount);
|
||||
}
|
||||
});
|
||||
|
||||
list_dicts(dicts_dir_list, json_output);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
std::list<std::string> disable_list;
|
||||
|
||||
if (use_dict_list) {
|
||||
std::list<std::string> empty_list;
|
||||
|
||||
for_each_file(dicts_dir_list, ".ifo", empty_list, empty_list,
|
||||
[&disable_list, &use_dict_list](const std::string &filename, bool) -> void {
|
||||
std::map<std::string, std::string> bookname_to_ifo;
|
||||
for_each_file(dicts_dir_list, ".ifo", std::list<std::string>(), std::list<std::string>(),
|
||||
[&bookname_to_ifo](const std::string &fname, bool) {
|
||||
DictInfo dict_info;
|
||||
const bool load_ok = dict_info.load_from_ifo_file(filename, false);
|
||||
const bool load_ok = dict_info.load_from_ifo_file(fname, false);
|
||||
if (!load_ok)
|
||||
return;
|
||||
|
||||
for (gchar **p = get_impl(use_dict_list); *p != nullptr; ++p)
|
||||
if (strcmp(*p, dict_info.bookname.c_str()) == 0)
|
||||
return;
|
||||
disable_list.push_back(dict_info.ifo_file_name);
|
||||
bookname_to_ifo[dict_info.bookname] = dict_info.ifo_file_name;
|
||||
});
|
||||
|
||||
std::list<std::string> order_list;
|
||||
if (use_dict_list != nullptr) {
|
||||
for (auto &&x : bookname_to_ifo) {
|
||||
gchar **p = get_impl(use_dict_list);
|
||||
for (; *p != nullptr; ++p)
|
||||
if (x.first.compare(*p) == 0) {
|
||||
break;
|
||||
}
|
||||
if (*p == nullptr) {
|
||||
disable_list.push_back(x.second);
|
||||
}
|
||||
}
|
||||
|
||||
// add bookname to list
|
||||
gchar **p = get_impl(use_dict_list);
|
||||
while (*p) {
|
||||
order_list.push_back(bookname_to_ifo.at(*p));
|
||||
++p;
|
||||
}
|
||||
} else {
|
||||
const std::string odering_cfg_file = std::string(homedir) + G_DIR_SEPARATOR_S ".sdcv_ordering";
|
||||
FILE *ordering_file = fopen(odering_cfg_file.c_str(), "r");
|
||||
if (ordering_file != nullptr) {
|
||||
std::string line;
|
||||
while (stdio_getline(ordering_file, line)) {
|
||||
order_list.push_back(bookname_to_ifo.at(line));
|
||||
}
|
||||
fclose(ordering_file);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string conf_dir = std::string(g_get_home_dir()) + G_DIR_SEPARATOR + ".stardict";
|
||||
if (g_mkdir(conf_dir.c_str(), S_IRWXU) == -1 && errno != EEXIST)
|
||||
if (g_mkdir(conf_dir.c_str(), S_IRWXU) == -1 && errno != EEXIST) {
|
||||
fprintf(stderr, _("g_mkdir failed: %s\n"), strerror(errno));
|
||||
}
|
||||
|
||||
Library lib(utf8_input, utf8_output, colorize);
|
||||
std::list<std::string> empty_list;
|
||||
lib.load(dicts_dir_list, empty_list, disable_list);
|
||||
Library lib(utf8_input, utf8_output, colorize, json_output, no_fuzzy);
|
||||
lib.load(dicts_dir_list, order_list, disable_list);
|
||||
|
||||
std::unique_ptr<IReadLine> io(create_readline_object());
|
||||
if (optind < argc) {
|
||||
for (int i = optind; i < argc; ++i)
|
||||
if (!lib.process_phrase(argv[i], *io, non_interactive))
|
||||
if (!lib.process_phrase(argv[i], *io, non_interactive)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else if (!non_interactive) {
|
||||
|
||||
std::string phrase;
|
||||
@@ -200,3 +229,32 @@ int main(int argc, char *argv[]) try {
|
||||
fprintf(stderr, "Internal error: %s\n", ex.what());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void list_dicts(const std::list<std::string> &dicts_dir_list, bool use_json)
|
||||
{
|
||||
bool first_entry = true;
|
||||
if (!use_json)
|
||||
printf(_("Dictionary's name Word count\n"));
|
||||
else
|
||||
fputc('[', stdout);
|
||||
std::list<std::string> order_list, disable_list;
|
||||
for_each_file(dicts_dir_list, ".ifo", order_list,
|
||||
disable_list, [use_json, &first_entry](const std::string &filename, bool) -> void {
|
||||
DictInfo dict_info;
|
||||
if (dict_info.load_from_ifo_file(filename, false)) {
|
||||
const std::string bookname = utf8_to_locale_ign_err(dict_info.bookname);
|
||||
if (use_json) {
|
||||
if (first_entry) {
|
||||
first_entry = false;
|
||||
} else {
|
||||
fputc(',', stdout); // comma between entries
|
||||
}
|
||||
printf("{\"name\": \"%s\", \"wordcount\": \"%d\"}", json_escape_string(bookname).c_str(), dict_info.wordcount);
|
||||
} else {
|
||||
printf("%s %d\n", bookname.c_str(), dict_info.wordcount);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (use_json)
|
||||
fputs("]\n", stdout);
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <zlib.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "distance.hpp"
|
||||
#include "mapfile.hpp"
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
#include "stardict_lib.hpp"
|
||||
|
||||
|
||||
#define TO_STR2(xstr) #xstr
|
||||
#define TO_STR1(xstr) TO_STR2(xstr)
|
||||
|
||||
#define THROW_IF_ERROR(expr) do { \
|
||||
#define THROW_IF_ERROR(expr) \
|
||||
do { \
|
||||
assert((expr)); \
|
||||
if (!(expr)) \
|
||||
throw std::runtime_error(#expr " not true at " __FILE__ ": " TO_STR1(__LINE__)); \
|
||||
@@ -30,7 +30,8 @@
|
||||
// Notice: read src/tools/DICTFILE_FORMAT for the dictionary
|
||||
// file's format information!
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
struct Fuzzystruct {
|
||||
char *pMatchWord;
|
||||
int iMatchWordDistance;
|
||||
@@ -70,7 +71,6 @@ namespace {
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool DictInfo::load_from_ifo_file(const std::string &ifofilename,
|
||||
@@ -89,7 +89,6 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
|
||||
if (!g_str_has_prefix(
|
||||
g_str_has_prefix(get_impl(buffer), (const gchar *)(utf8_bom)) ? get_impl(buffer) + 3 : get_impl(buffer),
|
||||
magic_data)) {
|
||||
g_free(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -100,10 +99,8 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
|
||||
return false;
|
||||
|
||||
gchar *p3 = strchr(p2 + sizeof("\nwordcount=") - 1, '\n');
|
||||
gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1);
|
||||
tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0';
|
||||
wordcount = atol(tmpstr);
|
||||
g_free(tmpstr);
|
||||
|
||||
wordcount = atol(std::string(p2 + sizeof("\nwordcount=") - 1, p3 - (p2 + sizeof("\nwordcount=") - 1)).c_str());
|
||||
|
||||
if (istreedict) {
|
||||
p2 = strstr(p1, "\ntdxfilesize=");
|
||||
@@ -111,10 +108,9 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
|
||||
return false;
|
||||
|
||||
p3 = strchr(p2 + sizeof("\ntdxfilesize=") - 1, '\n');
|
||||
tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1);
|
||||
tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0';
|
||||
index_file_size = atol(tmpstr);
|
||||
g_free(tmpstr);
|
||||
|
||||
index_file_size = atol(std::string(p2 + sizeof("\ntdxfilesize=") - 1, p3 - (p2 + sizeof("\ntdxfilesize=") - 1)).c_str());
|
||||
|
||||
} else {
|
||||
|
||||
p2 = strstr(p1, "\nidxfilesize=");
|
||||
@@ -122,10 +118,7 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
|
||||
return false;
|
||||
|
||||
p3 = strchr(p2 + sizeof("\nidxfilesize=") - 1, '\n');
|
||||
tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1);
|
||||
tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0';
|
||||
index_file_size = atol(tmpstr);
|
||||
g_free(tmpstr);
|
||||
index_file_size = atol(std::string(p2 + sizeof("\nidxfilesize=") - 1, p3 - (p2 + sizeof("\nidxfilesize=") - 1)).c_str());
|
||||
}
|
||||
|
||||
p2 = strstr(p1, "\nbookname=");
|
||||
@@ -179,6 +172,14 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
|
||||
sametypesequence.assign(p2, p3 - p2);
|
||||
}
|
||||
|
||||
p2 = strstr(p1, "\nsynwordcount=");
|
||||
syn_wordcount = 0;
|
||||
if (p2) {
|
||||
p2 += sizeof("\nsynwordcount=") - 1;
|
||||
p3 = strchr(p2, '\n');
|
||||
syn_wordcount = atol(std::string(p2, p3 - p2).c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -358,7 +359,6 @@ bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem
|
||||
++nfound;
|
||||
}
|
||||
|
||||
|
||||
if (nfound == nWord)
|
||||
return true;
|
||||
sec_size = strlen(p) + 1;
|
||||
@@ -384,13 +384,11 @@ bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem
|
||||
case 'k':
|
||||
sec_size = idxitem_size - (p - origin_data);
|
||||
for (j = 0; j < nWord; j++)
|
||||
if (!WordFind[j] &&
|
||||
g_strstr_len(p, sec_size, SearchWords[j].c_str())) {
|
||||
if (!WordFind[j] && g_strstr_len(p, sec_size, SearchWords[j].c_str())) {
|
||||
WordFind[j] = true;
|
||||
++nfound;
|
||||
}
|
||||
|
||||
|
||||
if (nfound == nWord)
|
||||
return true;
|
||||
break;
|
||||
@@ -430,21 +428,29 @@ bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class OffsetIndex : public IIndexFile {
|
||||
namespace
|
||||
{
|
||||
class OffsetIndex : public IIndexFile
|
||||
{
|
||||
public:
|
||||
OffsetIndex() : idxfile(nullptr) {}
|
||||
~OffsetIndex() {
|
||||
OffsetIndex()
|
||||
: idxfile(nullptr)
|
||||
{
|
||||
}
|
||||
~OffsetIndex()
|
||||
{
|
||||
if (idxfile)
|
||||
fclose(idxfile);
|
||||
}
|
||||
bool load(const std::string& url, gulong wc, gulong fsize) override;
|
||||
bool load(const std::string &url, gulong wc, gulong fsize, bool verbose) override;
|
||||
const gchar *get_key(glong idx) override;
|
||||
void get_data(glong idx) override { get_key(idx); }
|
||||
const gchar *get_key_and_data(glong idx) override {
|
||||
const gchar *get_key_and_data(glong idx) override
|
||||
{
|
||||
return get_key(idx);
|
||||
}
|
||||
bool lookup(const char *str, glong &idx) override;
|
||||
|
||||
private:
|
||||
static const gint ENTR_PER_PAGE = 32;
|
||||
static const char *CACHE_MAGIC;
|
||||
@@ -457,7 +463,8 @@ namespace {
|
||||
struct index_entry {
|
||||
glong idx;
|
||||
std::string keystr;
|
||||
void assign(glong i, const std::string& str) {
|
||||
void assign(glong i, const std::string &str)
|
||||
{
|
||||
idx = i;
|
||||
keystr.assign(str);
|
||||
}
|
||||
@@ -480,25 +487,30 @@ namespace {
|
||||
const gchar *read_first_on_page_key(glong page_idx);
|
||||
const gchar *get_first_on_page_key(glong page_idx);
|
||||
bool load_cache(const std::string &url);
|
||||
bool save_cache(const std::string& url);
|
||||
bool save_cache(const std::string &url, bool verbose);
|
||||
static std::list<std::string> get_cache_variant(const std::string &url);
|
||||
};
|
||||
|
||||
const char *OffsetIndex::CACHE_MAGIC = "StarDict's Cache, Version: 0.1";
|
||||
|
||||
|
||||
class WordListIndex : public IIndexFile {
|
||||
class WordListIndex : public IIndexFile
|
||||
{
|
||||
public:
|
||||
WordListIndex() : idxdatabuf(nullptr) {}
|
||||
WordListIndex()
|
||||
: idxdatabuf(nullptr)
|
||||
{
|
||||
}
|
||||
~WordListIndex() { g_free(idxdatabuf); }
|
||||
bool load(const std::string& url, gulong wc, gulong fsize) override;
|
||||
bool load(const std::string &url, gulong wc, gulong fsize, bool verbose) override;
|
||||
const gchar *get_key(glong idx) override { return wordlist[idx]; }
|
||||
void get_data(glong idx) override;
|
||||
const gchar *get_key_and_data(glong idx) override {
|
||||
const gchar *get_key_and_data(glong idx) override
|
||||
{
|
||||
get_data(idx);
|
||||
return get_key(idx);
|
||||
}
|
||||
bool lookup(const char *str, glong &idx) override;
|
||||
|
||||
private:
|
||||
gchar *idxdatabuf;
|
||||
std::vector<gchar *> wordlist;
|
||||
@@ -552,8 +564,7 @@ namespace {
|
||||
|
||||
for (const std::string &item : vars) {
|
||||
struct ::stat idxstat, cachestat;
|
||||
if (g_stat(url.c_str(), &idxstat)!=0 ||
|
||||
g_stat(item.c_str(), &cachestat)!=0)
|
||||
if (g_stat(url.c_str(), &idxstat) != 0 || g_stat(item.c_str(), &cachestat) != 0)
|
||||
continue;
|
||||
if (cachestat.st_mtime < idxstat.st_mtime)
|
||||
continue;
|
||||
@@ -564,7 +575,6 @@ namespace {
|
||||
continue;
|
||||
memcpy(&wordoffset[0], mf.begin() + strlen(CACHE_MAGIC), wordoffset.size() * sizeof(wordoffset[0]));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -573,8 +583,7 @@ namespace {
|
||||
std::list<std::string> OffsetIndex::get_cache_variant(const std::string &url)
|
||||
{
|
||||
std::list<std::string> res = { url + ".oft" };
|
||||
if (!g_file_test(g_get_user_cache_dir(), G_FILE_TEST_EXISTS) &&
|
||||
g_mkdir(g_get_user_cache_dir(), 0700)==-1)
|
||||
if (!g_file_test(g_get_user_cache_dir(), G_FILE_TEST_EXISTS) && g_mkdir(g_get_user_cache_dir(), 0700) == -1)
|
||||
return res;
|
||||
|
||||
const std::string cache_dir = std::string(g_get_user_cache_dir()) + G_DIR_SEPARATOR_S + "sdcv";
|
||||
@@ -591,7 +600,7 @@ namespace {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool OffsetIndex::save_cache(const std::string& url)
|
||||
bool OffsetIndex::save_cache(const std::string &url, bool verbose)
|
||||
{
|
||||
const std::list<std::string> vars = get_cache_variant(url);
|
||||
for (const std::string &item : vars) {
|
||||
@@ -603,13 +612,15 @@ namespace {
|
||||
if (fwrite(&wordoffset[0], sizeof(wordoffset[0]), wordoffset.size(), out) != wordoffset.size())
|
||||
continue;
|
||||
fclose(out);
|
||||
if (verbose) {
|
||||
printf("save to cache %s\n", url.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OffsetIndex::load(const std::string& url, gulong wc, gulong fsize)
|
||||
bool OffsetIndex::load(const std::string &url, gulong wc, gulong fsize, bool verbose)
|
||||
{
|
||||
wordcount = wc;
|
||||
gulong npages = (wc - 1) / ENTR_PER_PAGE + 2;
|
||||
@@ -632,7 +643,7 @@ namespace {
|
||||
p1 += index_size;
|
||||
}
|
||||
wordoffset[j] = p1 - idxdatabuffer;
|
||||
if (!save_cache(url))
|
||||
if (!save_cache(url, verbose))
|
||||
fprintf(stderr, "cache update failed\n");
|
||||
}
|
||||
|
||||
@@ -656,7 +667,6 @@ namespace {
|
||||
if ((nentr = (wordcount % ENTR_PER_PAGE)) == 0)
|
||||
nentr = ENTR_PER_PAGE;
|
||||
|
||||
|
||||
if (page_idx != page.idx) {
|
||||
page_data.resize(wordoffset[page_idx + 1] - wordoffset[page_idx]);
|
||||
fseek(idxfile, wordoffset[page_idx], SEEK_SET);
|
||||
@@ -740,7 +750,7 @@ namespace {
|
||||
return bFound;
|
||||
}
|
||||
|
||||
bool WordListIndex::load(const std::string& url, gulong wc, gulong fsize)
|
||||
bool WordListIndex::load(const std::string &url, gulong wc, gulong fsize, bool verbose)
|
||||
{
|
||||
gzFile in = gzopen(url.c_str(), "rb");
|
||||
if (in == nullptr)
|
||||
@@ -810,7 +820,48 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool Dict::load(const std::string& ifofilename)
|
||||
bool SynFile::load(const std::string &url, gulong wc)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if (!stat(url.c_str(), &stat_buf)) {
|
||||
MapFile syn;
|
||||
if (!syn.open(url.c_str(), stat_buf.st_size))
|
||||
return false;
|
||||
const gchar *current = syn.begin();
|
||||
for (unsigned long i = 0; i < wc; i++) {
|
||||
// each entry in a syn-file is:
|
||||
// - 0-terminated string
|
||||
// 4-byte index into .dict file in network byte order
|
||||
glib::CharStr lower_string{ g_utf8_casefold(current, -1) };
|
||||
std::string synonym{ get_impl(lower_string) };
|
||||
current += synonym.length() + 1;
|
||||
const guint32 idx = g_ntohl(get_uint32(current));
|
||||
current += sizeof(idx);
|
||||
synonyms[synonym] = idx;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SynFile::lookup(const char *str, glong &idx)
|
||||
{
|
||||
glib::CharStr lower_string{ g_utf8_casefold(str, -1) };
|
||||
auto it = synonyms.find(get_impl(lower_string));
|
||||
if (it != synonyms.end()) {
|
||||
idx = it->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Dict::Lookup(const char *str, glong &idx)
|
||||
{
|
||||
return syn_file->lookup(str, idx) || idx_file->lookup(str, idx);
|
||||
}
|
||||
|
||||
bool Dict::load(const std::string &ifofilename, bool verbose)
|
||||
{
|
||||
gulong idxfilesize;
|
||||
if (!load_ifofile(ifofilename, idxfilesize))
|
||||
@@ -844,9 +895,14 @@ bool Dict::load(const std::string& ifofilename)
|
||||
idx_file.reset(new OffsetIndex);
|
||||
}
|
||||
|
||||
if (!idx_file->load(fullfilename, wordcount, idxfilesize))
|
||||
if (!idx_file->load(fullfilename, wordcount, idxfilesize, verbose))
|
||||
return false;
|
||||
|
||||
fullfilename = ifofilename;
|
||||
fullfilename.replace(fullfilename.length() - sizeof("ifo") + 1, sizeof("ifo") - 1, "syn");
|
||||
syn_file.reset(new SynFile);
|
||||
syn_file->load(fullfilename, syn_wordcount);
|
||||
|
||||
//g_print("bookname: %s , wordcount %lu\n", bookname.c_str(), narticles());
|
||||
return true;
|
||||
}
|
||||
@@ -861,6 +917,7 @@ bool Dict::load_ifofile(const std::string& ifofilename, gulong &idxfilesize)
|
||||
|
||||
ifo_file_name = dict_info.ifo_file_name;
|
||||
wordcount = dict_info.wordcount;
|
||||
syn_wordcount = dict_info.syn_wordcount;
|
||||
bookname = dict_info.bookname;
|
||||
|
||||
idxfilesize = dict_info.index_file_size;
|
||||
@@ -892,7 +949,7 @@ Libs::~Libs()
|
||||
void Libs::load_dict(const std::string &url)
|
||||
{
|
||||
Dict *lib = new Dict;
|
||||
if (lib->load(url))
|
||||
if (lib->load(url, verbose_))
|
||||
oLib.push_back(lib);
|
||||
else
|
||||
delete lib;
|
||||
@@ -909,33 +966,6 @@ void Libs::load(const std::list<std::string>& dicts_dirs,
|
||||
});
|
||||
}
|
||||
|
||||
void Libs::reload(const std::list<std::string>& dicts_dirs,
|
||||
const std::list<std::string>& order_list,
|
||||
const std::list<std::string>& disable_list)
|
||||
{
|
||||
std::vector<Dict *> prev(oLib);
|
||||
oLib.clear();
|
||||
|
||||
for_each_file(dicts_dirs, ".ifo", order_list, disable_list,
|
||||
[&prev, this](const std::string& url, bool disable) -> void {
|
||||
if (!disable) {
|
||||
auto it = prev.begin();
|
||||
for (; it != prev.end(); ++it)
|
||||
if ((*it)->ifofilename() == url)
|
||||
break;
|
||||
if (it != prev.end()) {
|
||||
Dict *res = *it;
|
||||
prev.erase(it);
|
||||
oLib.push_back(res);
|
||||
} else
|
||||
load_dict(url);
|
||||
}
|
||||
});
|
||||
|
||||
for (Dict *p : prev)
|
||||
delete p;
|
||||
}
|
||||
|
||||
const gchar *Libs::poGetCurrentWord(glong *iCurrent)
|
||||
{
|
||||
const gchar *poCurrentWord = nullptr;
|
||||
@@ -1002,7 +1032,6 @@ const gchar *Libs::poGetNextWord(const gchar *sWord, glong *iCurrent)
|
||||
return poCurrentWord;
|
||||
}
|
||||
|
||||
|
||||
const gchar *
|
||||
Libs::poGetPreWord(glong *iCurrent)
|
||||
{
|
||||
@@ -1120,8 +1149,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
|
||||
strcpy(sNewWord, sWord);
|
||||
sNewWord[iWordLen - 2] = '\0'; // cut "ly"
|
||||
if (iWordLen > 5 && sNewWord[iWordLen - 3] == sNewWord[iWordLen - 4]
|
||||
&& !bIsVowel(sNewWord[iWordLen-4]) &&
|
||||
bIsVowel(sNewWord[iWordLen-5])) {//doubled
|
||||
&& !bIsVowel(sNewWord[iWordLen - 4]) && bIsVowel(sNewWord[iWordLen - 5])) { //doubled
|
||||
|
||||
sNewWord[iWordLen - 3] = '\0';
|
||||
if (oLib[iLib]->Lookup(sNewWord, iIndex))
|
||||
@@ -1161,8 +1189,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
|
||||
strcpy(sNewWord, sWord);
|
||||
sNewWord[iWordLen - 3] = '\0';
|
||||
if (iWordLen > 6 && (sNewWord[iWordLen - 4] == sNewWord[iWordLen - 5])
|
||||
&& !bIsVowel(sNewWord[iWordLen-5]) &&
|
||||
bIsVowel(sNewWord[iWordLen-6])) { //doubled
|
||||
&& !bIsVowel(sNewWord[iWordLen - 5]) && bIsVowel(sNewWord[iWordLen - 6])) { //doubled
|
||||
sNewWord[iWordLen - 4] = '\0';
|
||||
if (oLib[iLib]->Lookup(sNewWord, iIndex))
|
||||
bFound = true;
|
||||
@@ -1212,19 +1239,8 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
|
||||
|
||||
//cut two char "es"
|
||||
if (!bFound && iWordLen > 3) {
|
||||
isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) &&
|
||||
(sWord[iWordLen-3] == 'S' ||
|
||||
sWord[iWordLen-3] == 'X' ||
|
||||
sWord[iWordLen-3] == 'O' ||
|
||||
(iWordLen >4 && sWord[iWordLen-3] == 'H' &&
|
||||
(sWord[iWordLen-4] == 'C' ||
|
||||
sWord[iWordLen-4] == 'S'))));
|
||||
if (isupcase ||
|
||||
(!strncmp(&sWord[iWordLen-2],"es",2) &&
|
||||
(sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' ||
|
||||
sWord[iWordLen-3] == 'o' ||
|
||||
(iWordLen >4 && sWord[iWordLen-3] == 'h' &&
|
||||
(sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) {
|
||||
isupcase = (!strncmp(&sWord[iWordLen - 2], "ES", 2) && (sWord[iWordLen - 3] == 'S' || sWord[iWordLen - 3] == 'X' || sWord[iWordLen - 3] == 'O' || (iWordLen > 4 && sWord[iWordLen - 3] == 'H' && (sWord[iWordLen - 4] == 'C' || sWord[iWordLen - 4] == 'S'))));
|
||||
if (isupcase || (!strncmp(&sWord[iWordLen - 2], "es", 2) && (sWord[iWordLen - 3] == 's' || sWord[iWordLen - 3] == 'x' || sWord[iWordLen - 3] == 'o' || (iWordLen > 4 && sWord[iWordLen - 3] == 'h' && (sWord[iWordLen - 4] == 'c' || sWord[iWordLen - 4] == 's'))))) {
|
||||
strcpy(sNewWord, sWord);
|
||||
sNewWord[iWordLen - 2] = '\0';
|
||||
if (oLib[iLib]->Lookup(sNewWord, iIndex))
|
||||
@@ -1247,8 +1263,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
|
||||
strcpy(sNewWord, sWord);
|
||||
sNewWord[iWordLen - 2] = '\0';
|
||||
if (iWordLen > 5 && (sNewWord[iWordLen - 3] == sNewWord[iWordLen - 4])
|
||||
&& !bIsVowel(sNewWord[iWordLen-4]) &&
|
||||
bIsVowel(sNewWord[iWordLen-5])) {//doubled
|
||||
&& !bIsVowel(sNewWord[iWordLen - 4]) && bIsVowel(sNewWord[iWordLen - 5])) { //doubled
|
||||
sNewWord[iWordLen - 3] = '\0';
|
||||
if (oLib[iLib]->Lookup(sNewWord, iIndex))
|
||||
bFound = true;
|
||||
@@ -1382,7 +1397,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
|
||||
bool Libs::SimpleLookupWord(const gchar *sWord, glong &iWordIndex, int iLib)
|
||||
{
|
||||
bool bFound = oLib[iLib]->Lookup(sWord, iWordIndex);
|
||||
if (!bFound)
|
||||
if (!bFound && fuzzy_)
|
||||
bFound = LookupSimilarWord(sWord, iWordIndex, iLib);
|
||||
return bFound;
|
||||
}
|
||||
@@ -1423,8 +1438,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
|
||||
sCheck = poGetWord(index, iLib);
|
||||
// tolower and skip too long or too short words
|
||||
iCheckWordLen = g_utf8_strlen(sCheck, -1);
|
||||
if (iCheckWordLen-ucs4_str2_len>=iMaxDistance ||
|
||||
ucs4_str2_len-iCheckWordLen>=iMaxDistance)
|
||||
if (iCheckWordLen - ucs4_str2_len >= iMaxDistance || ucs4_str2_len - iCheckWordLen >= iMaxDistance)
|
||||
continue;
|
||||
ucs4_str1 = g_utf8_to_ucs4_fast(sCheck, -1, nullptr);
|
||||
if (iCheckWordLen > ucs4_str2_len)
|
||||
@@ -1439,8 +1453,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
|
||||
bool bAlreadyInList = false;
|
||||
int iMaxDistanceAt = 0;
|
||||
for (int j = 0; j < reslist_size; j++) {
|
||||
if (oFuzzystruct[j].pMatchWord &&
|
||||
strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) {//already in list
|
||||
if (oFuzzystruct[j].pMatchWord && strcmp(oFuzzystruct[j].pMatchWord, sCheck) == 0) { //already in list
|
||||
bAlreadyInList = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "dictziplib.hpp"
|
||||
|
||||
@@ -25,7 +26,6 @@ inline void set_uint32(gchar *addr, guint32 val)
|
||||
memcpy(addr, &val, sizeof(guint32));
|
||||
}
|
||||
|
||||
|
||||
struct cacheItem {
|
||||
guint32 offset;
|
||||
gchar *data;
|
||||
@@ -37,26 +37,31 @@ struct cacheItem {
|
||||
const int WORDDATA_CACHE_NUM = 10;
|
||||
const int INVALID_INDEX = -100;
|
||||
|
||||
class DictBase {
|
||||
class DictBase
|
||||
{
|
||||
public:
|
||||
DictBase() {}
|
||||
~DictBase() {
|
||||
~DictBase()
|
||||
{
|
||||
if (dictfile)
|
||||
fclose(dictfile);
|
||||
}
|
||||
DictBase(const DictBase &) = delete;
|
||||
DictBase &operator=(const DictBase &) = delete;
|
||||
gchar *GetWordData(guint32 idxitem_offset, guint32 idxitem_size);
|
||||
bool containSearchData() const {
|
||||
bool containSearchData() const
|
||||
{
|
||||
if (sametypesequence.empty())
|
||||
return true;
|
||||
return sametypesequence.find_first_of("mlgxty") != std::string::npos;
|
||||
}
|
||||
bool SearchData(std::vector<std::string> &SearchWords, guint32 idxitem_offset, guint32 idxitem_size, gchar *origin_data);
|
||||
|
||||
protected:
|
||||
std::string sametypesequence;
|
||||
FILE *dictfile = nullptr;
|
||||
std::unique_ptr<DictData> dictdzfile;
|
||||
|
||||
private:
|
||||
cacheItem cache[WORDDATA_CACHE_NUM];
|
||||
gint cache_cur = 0;
|
||||
@@ -66,6 +71,7 @@ private:
|
||||
struct DictInfo {
|
||||
std::string ifo_file_name;
|
||||
guint32 wordcount;
|
||||
guint32 syn_wordcount;
|
||||
std::string bookname;
|
||||
std::string author;
|
||||
std::string email;
|
||||
@@ -73,64 +79,86 @@ struct DictInfo {
|
||||
std::string date;
|
||||
std::string description;
|
||||
guint32 index_file_size;
|
||||
guint32 syn_file_size;
|
||||
std::string sametypesequence;
|
||||
|
||||
bool load_from_ifo_file(const std::string &ifofilename, bool istreedict);
|
||||
};
|
||||
|
||||
class IIndexFile {
|
||||
class IIndexFile
|
||||
{
|
||||
public:
|
||||
guint32 wordentry_offset;
|
||||
guint32 wordentry_size;
|
||||
|
||||
virtual ~IIndexFile() {}
|
||||
virtual bool load(const std::string& url, gulong wc, gulong fsize) = 0;
|
||||
virtual bool load(const std::string &url, gulong wc, gulong fsize, bool verbose) = 0;
|
||||
virtual const gchar *get_key(glong idx) = 0;
|
||||
virtual void get_data(glong idx) = 0;
|
||||
virtual const gchar *get_key_and_data(glong idx) = 0;
|
||||
virtual bool lookup(const char *str, glong &idx) = 0;
|
||||
};
|
||||
|
||||
class Dict : public DictBase {
|
||||
class SynFile
|
||||
{
|
||||
public:
|
||||
bool load(const std::string &url, gulong wc);
|
||||
bool lookup(const char *str, glong &idx);
|
||||
|
||||
private:
|
||||
std::map<std::string, gulong> synonyms;
|
||||
};
|
||||
|
||||
class Dict : public DictBase
|
||||
{
|
||||
public:
|
||||
Dict() {}
|
||||
Dict(const Dict &) = delete;
|
||||
Dict &operator=(const Dict &) = delete;
|
||||
bool load(const std::string& ifofilename);
|
||||
bool load(const std::string &ifofilename, bool verbose);
|
||||
|
||||
gulong narticles() const { return wordcount; }
|
||||
const std::string &dict_name() const { return bookname; }
|
||||
const std::string &ifofilename() const { return ifo_file_name; }
|
||||
|
||||
const gchar *get_key(glong index) { return idx_file->get_key(index); }
|
||||
gchar *get_data(glong index) {
|
||||
gchar *get_data(glong index)
|
||||
{
|
||||
idx_file->get_data(index);
|
||||
return DictBase::GetWordData(idx_file->wordentry_offset, idx_file->wordentry_size);
|
||||
}
|
||||
void get_key_and_data(glong index, const gchar **key, guint32 *offset, guint32 *size) {
|
||||
void get_key_and_data(glong index, const gchar **key, guint32 *offset, guint32 *size)
|
||||
{
|
||||
*key = idx_file->get_key_and_data(index);
|
||||
*offset = idx_file->wordentry_offset;
|
||||
*size = idx_file->wordentry_size;
|
||||
}
|
||||
bool Lookup(const char *str, glong &idx) { return idx_file->lookup(str, idx); }
|
||||
bool Lookup(const char *str, glong &idx);
|
||||
|
||||
bool LookupWithRule(GPatternSpec *pspec, glong *aIndex, int iBuffLen);
|
||||
|
||||
private:
|
||||
std::string ifo_file_name;
|
||||
gulong wordcount;
|
||||
gulong syn_wordcount;
|
||||
std::string bookname;
|
||||
|
||||
std::unique_ptr<IIndexFile> idx_file;
|
||||
std::unique_ptr<SynFile> syn_file;
|
||||
|
||||
bool load_ifofile(const std::string &ifofilename, gulong &idxfilesize);
|
||||
};
|
||||
|
||||
class Libs {
|
||||
class Libs
|
||||
{
|
||||
public:
|
||||
Libs(std::function<void(void)> f = std::function<void(void)>()) {
|
||||
Libs(std::function<void(void)> f = std::function<void(void)>())
|
||||
{
|
||||
progress_func = f;
|
||||
iMaxFuzzyDistance = MAX_FUZZY_DISTANCE; //need to read from cfg.
|
||||
}
|
||||
void setVerbose(bool verbose) { verbose_ = verbose; }
|
||||
void setFuzzy(bool fuzzy) { fuzzy_ = fuzzy; }
|
||||
~Libs();
|
||||
Libs(const Libs &) = delete;
|
||||
Libs &operator=(const Libs &) = delete;
|
||||
@@ -139,18 +167,16 @@ public:
|
||||
void load(const std::list<std::string> &dicts_dirs,
|
||||
const std::list<std::string> &order_list,
|
||||
const std::list<std::string> &disable_list);
|
||||
void reload(const std::list<std::string>& dicts_dirs,
|
||||
const std::list<std::string>& order_list,
|
||||
const std::list<std::string>& disable_list);
|
||||
|
||||
glong narticles(int idict) const { return oLib[idict]->narticles(); }
|
||||
const std::string &dict_name(int idict) const { return oLib[idict]->dict_name(); }
|
||||
gint ndicts() const { return oLib.size(); }
|
||||
|
||||
const gchar *poGetWord(glong iIndex, int iLib) {
|
||||
const gchar *poGetWord(glong iIndex, int iLib)
|
||||
{
|
||||
return oLib[iLib]->get_key(iIndex);
|
||||
}
|
||||
gchar * poGetWordData(glong iIndex,int iLib) {
|
||||
gchar *poGetWordData(glong iIndex, int iLib)
|
||||
{
|
||||
if (iIndex == INVALID_INDEX)
|
||||
return nullptr;
|
||||
return oLib[iLib]->get_data(iIndex);
|
||||
@@ -158,26 +184,32 @@ public:
|
||||
const gchar *poGetCurrentWord(glong *iCurrent);
|
||||
const gchar *poGetNextWord(const gchar *word, glong *iCurrent);
|
||||
const gchar *poGetPreWord(glong *iCurrent);
|
||||
bool LookupWord(const gchar* sWord, glong& iWordIndex, int iLib) {
|
||||
bool LookupWord(const gchar *sWord, glong &iWordIndex, int iLib)
|
||||
{
|
||||
return oLib[iLib]->Lookup(sWord, iWordIndex);
|
||||
}
|
||||
bool LookupSimilarWord(const gchar *sWord, glong &iWordIndex, int iLib);
|
||||
bool SimpleLookupWord(const gchar *sWord, glong &iWordIndex, int iLib);
|
||||
|
||||
|
||||
bool LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_size);
|
||||
gint LookupWithRule(const gchar *sWord, gchar *reslist[]);
|
||||
bool LookupData(const gchar *sWord, std::vector<gchar *> *reslist);
|
||||
|
||||
protected:
|
||||
bool fuzzy_;
|
||||
|
||||
private:
|
||||
std::vector<Dict *> oLib; // word Libs.
|
||||
int iMaxFuzzyDistance;
|
||||
std::function<void(void)> progress_func;
|
||||
bool verbose_;
|
||||
};
|
||||
|
||||
|
||||
enum query_t {
|
||||
qtSIMPLE, qtREGEXP, qtFUZZY, qtDATA
|
||||
qtSIMPLE,
|
||||
qtREGEXP,
|
||||
qtFUZZY,
|
||||
qtDATA
|
||||
};
|
||||
|
||||
extern query_t analyze_query(const char *s, std::string &res);
|
||||
|
||||
|
||||
@@ -15,18 +15,20 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
@@ -65,12 +67,11 @@ static void __for_each_file(const std::string& dirname, const std::string& suff,
|
||||
const std::string fullfilename(dirname + G_DIR_SEPARATOR_S + filename);
|
||||
if (g_file_test(fullfilename.c_str(), G_FILE_TEST_IS_DIR))
|
||||
__for_each_file(fullfilename, suff, order_list, disable_list, f);
|
||||
else if (g_str_has_suffix(filename, suff.c_str()) &&
|
||||
std::find(order_list.begin(), order_list.end(),
|
||||
fullfilename)==order_list.end()) {
|
||||
else if (g_str_has_suffix(filename, suff.c_str()) && std::find(order_list.begin(), order_list.end(), fullfilename) == order_list.end()) {
|
||||
const bool disable = std::find(disable_list.begin(),
|
||||
disable_list.end(),
|
||||
fullfilename)!=disable_list.end();
|
||||
fullfilename)
|
||||
!= disable_list.end();
|
||||
f(fullfilename, disable);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +79,6 @@ static void __for_each_file(const std::string& dirname, const std::string& suff,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void for_each_file(const std::list<std::string> &dirs_list, const std::string &suff,
|
||||
const std::list<std::string> &order_list, const std::list<std::string> &disable_list,
|
||||
const std::function<void(const std::string &, bool)> &f)
|
||||
@@ -90,3 +90,42 @@ void for_each_file(const std::list<std::string>& dirs_list, const std::string& s
|
||||
for (const std::string &item : dirs_list)
|
||||
__for_each_file(item, suff, order_list, disable_list, f);
|
||||
}
|
||||
|
||||
// based on https://stackoverflow.com/questions/7724448/simple-json-string-escape-for-c/33799784#33799784
|
||||
std::string json_escape_string(const std::string &s)
|
||||
{
|
||||
std::ostringstream o;
|
||||
for (auto c = s.cbegin(); c != s.cend(); c++) {
|
||||
switch (*c) {
|
||||
case '"':
|
||||
o << "\\\"";
|
||||
break;
|
||||
case '\\':
|
||||
o << "\\\\";
|
||||
break;
|
||||
case '\b':
|
||||
o << "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
o << "\\f";
|
||||
break;
|
||||
case '\n':
|
||||
o << "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
o << "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
o << "\\t";
|
||||
break;
|
||||
default:
|
||||
if ('\x00' <= *c && *c <= '\x1f') {
|
||||
o << "\\u"
|
||||
<< std::hex << std::setw(4) << std::setfill('0') << (int)*c;
|
||||
} else {
|
||||
o << *c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return o.str();
|
||||
}
|
||||
|
||||
@@ -1,62 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <glib.h>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
template <typename T, typename unref_res_t, void (*unref_res)(unref_res_t *)>
|
||||
class ResourceWrapper {
|
||||
class ResourceWrapper
|
||||
{
|
||||
public:
|
||||
ResourceWrapper(T *p = nullptr) : p_(p) {}
|
||||
ResourceWrapper(T *p = nullptr)
|
||||
: p_(p)
|
||||
{
|
||||
}
|
||||
~ResourceWrapper() { free_resource(); }
|
||||
ResourceWrapper(const ResourceWrapper &) = delete;
|
||||
ResourceWrapper &operator=(const ResourceWrapper &) = delete;
|
||||
T *operator->() const { return p_; }
|
||||
bool operator!() const { return p_ == nullptr; }
|
||||
const T& operator[](size_t idx) const {
|
||||
const T &operator[](size_t idx) const
|
||||
{
|
||||
assert(p_ != nullptr);
|
||||
return p_[idx];
|
||||
}
|
||||
|
||||
void reset(T *newp) {
|
||||
void reset(T *newp)
|
||||
{
|
||||
if (p_ != newp) {
|
||||
free_resource();
|
||||
p_ = newp;
|
||||
}
|
||||
}
|
||||
|
||||
friend inline T *get_impl(const ResourceWrapper& rw) {
|
||||
friend inline bool operator==(const ResourceWrapper &lhs, std::nullptr_t) noexcept
|
||||
{
|
||||
return !lhs.p_;
|
||||
}
|
||||
|
||||
friend inline bool operator!=(const ResourceWrapper &lhs, std::nullptr_t) noexcept
|
||||
{
|
||||
return !!lhs.p_;
|
||||
}
|
||||
|
||||
friend inline T *get_impl(const ResourceWrapper &rw)
|
||||
{
|
||||
return rw.p_;
|
||||
}
|
||||
|
||||
friend inline T **get_addr(ResourceWrapper& rw) {
|
||||
friend inline T **get_addr(ResourceWrapper &rw)
|
||||
{
|
||||
return &rw.p_;
|
||||
}
|
||||
|
||||
private:
|
||||
T *p_;
|
||||
|
||||
void free_resource() { if (p_) unref_res(p_); }
|
||||
|
||||
// Helper for enabling 'if (sp)'
|
||||
struct Tester {
|
||||
Tester() {}
|
||||
private:
|
||||
void operator delete(void*);
|
||||
};
|
||||
public:
|
||||
// enable 'if (sp)'
|
||||
operator Tester*() const {
|
||||
if (!*this)
|
||||
return 0;
|
||||
static Tester t;
|
||||
return &t;
|
||||
void free_resource()
|
||||
{
|
||||
if (p_)
|
||||
unref_res(p_);
|
||||
}
|
||||
};
|
||||
|
||||
namespace glib {
|
||||
namespace glib
|
||||
{
|
||||
typedef ResourceWrapper<gchar, void, g_free> CharStr;
|
||||
typedef ResourceWrapper<GError, GError, g_error_free> Error;
|
||||
}
|
||||
@@ -66,3 +75,4 @@ extern std::string utf8_to_locale_ign_err(const std::string& utf8_str);
|
||||
extern void for_each_file(const std::list<std::string> &dirs_list, const std::string &suff,
|
||||
const std::list<std::string> &order_list, const std::list<std::string> &disable_list,
|
||||
const std::function<void(const std::string &, bool)> &f);
|
||||
extern std::string json_escape_string(const std::string &str);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
//g++ `pkg-config --cflags glib-2.0` call_stardict_strcmp.cpp `pkg-config --libs glib-2.0`
|
||||
#include <glib.h>
|
||||
#include <locale.h>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
static inline gint stardict_strcmp(const gchar *s1, const gchar *s2)
|
||||
{
|
||||
const gint a = g_ascii_strcasecmp(s1, s2);
|
||||
if (a == 0)
|
||||
return strcmp(s1, s2);
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
std::cin.sync_with_stdio(false);
|
||||
std::string line1, line2;
|
||||
while (std::getline(std::cin, line1) &&
|
||||
std::getline(std::cin, line2)) {
|
||||
std::cout << stardict_strcmp(line1.c_str(), line2.c_str()) << "\n";
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import random, sys
|
||||
|
||||
fname = "/home/evgeniy/projects/competitions/words/data/words.txt"
|
||||
|
||||
with open(fname, "r") as fin:
|
||||
words = sorted(set([word.strip() for word in fin.readlines()]))
|
||||
res = []
|
||||
for i in range(0, len(words)):
|
||||
max_idx = len(words) - 1
|
||||
idx1 = random.randint(0, max_idx)
|
||||
idx2 = random.randint(0, max_idx)
|
||||
res.append((words[idx1], words[idx2]))
|
||||
|
||||
letters = "abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфкцчщьъэюя"
|
||||
letters += letters.upper()
|
||||
letters += " \t!@#$%^&*()[]"
|
||||
|
||||
def gen_word(req_word_len):
|
||||
max_idx = len(letters) - 1
|
||||
res = ""
|
||||
for i in range(0, req_word_len):
|
||||
res += letters[random.randint(0, max_idx)]
|
||||
return res
|
||||
|
||||
for i in range(0, 10000):
|
||||
l1 = random.randint(1, 100)
|
||||
l2 = random.randint(1, 100)
|
||||
res.append((gen_word(l1), gen_word(l2)))
|
||||
|
||||
for i in range(0, 10000):
|
||||
l1 = random.randint(1, 100)
|
||||
res.append((gen_word(l1), gen_word(l1)))
|
||||
|
||||
for item in res:
|
||||
print(item[0])
|
||||
print(item[1])
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
tests/stardict-test_synonyms-2.4.2/test.dict.dz
Normal file
BIN
tests/stardict-test_synonyms-2.4.2/test.dict.dz
Normal file
Binary file not shown.
BIN
tests/stardict-test_synonyms-2.4.2/test.idx
Normal file
BIN
tests/stardict-test_synonyms-2.4.2/test.idx
Normal file
Binary file not shown.
7
tests/stardict-test_synonyms-2.4.2/test.ifo
Normal file
7
tests/stardict-test_synonyms-2.4.2/test.ifo
Normal file
@@ -0,0 +1,7 @@
|
||||
StarDict's dict ifo file
|
||||
version=2.4.2
|
||||
bookname=Test synonyms
|
||||
wordcount=2
|
||||
synwordcount=2
|
||||
idxfilesize=32
|
||||
sametypesequence=m
|
||||
BIN
tests/stardict-test_synonyms-2.4.2/test.syn
Normal file
BIN
tests/stardict-test_synonyms-2.4.2/test.syn
Normal file
Binary file not shown.
23
tests/stardict-test_synonyms-2.4.2/test.xml
Normal file
23
tests/stardict-test_synonyms-2.4.2/test.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<stardict xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<info>
|
||||
<version>2.4.2</version>
|
||||
<bookname>Test synonyms</bookname>
|
||||
<author></author>
|
||||
<email></email>
|
||||
<website></website>
|
||||
<description></description>
|
||||
<date></date>
|
||||
<dicttype></dicttype>
|
||||
</info>
|
||||
<article><key>test</key><synonym>foo</synonym><synonym>bar</synonym>
|
||||
<definition type="m">
|
||||
<![CDATA[result of test]]>
|
||||
</definition>
|
||||
</article>
|
||||
<article><key>testawordy</key>
|
||||
<definition type="m">
|
||||
<![CDATA[word that ends in y to test with fuzzy search in -ied]]>
|
||||
</definition>
|
||||
</article>
|
||||
</stardict>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
24
tests/t_exact
Executable file
24
tests/t_exact
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
SDCV="$1"
|
||||
TEST_DIR="$2"
|
||||
|
||||
unset SDCV_PAGER
|
||||
|
||||
test_word() {
|
||||
WORD=$1
|
||||
EXPECTED=$2
|
||||
TAG=$3
|
||||
RES=$($SDCV -e -n --data-dir "$TEST_DIR" -u "Test synonyms" $WORD | grep "$TAG")
|
||||
if [ "$EXPECTED" != "$RES" ]; then
|
||||
echo "synonym for $WORD should be '$EXPECTED' but was '$RES'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_word testawordies "Nothing similar to testawordies, sorry :(" "Nothing similar"
|
||||
test_word testawordy "word that ends in y to test with fuzzy search in -ied" "fuzzy"
|
||||
|
||||
exit 0
|
||||
25
tests/t_json
Executable file
25
tests/t_json
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
SDCV="$1"
|
||||
TEST_DIR="$2"
|
||||
|
||||
unset SDCV_PAGER
|
||||
unset STARDICT_DATA_DIR
|
||||
|
||||
test_json() {
|
||||
PARAMS="$1"
|
||||
EXPECTED=$(echo "$2" | jq 'sort')
|
||||
RESULT=$($SDCV $PARAMS | jq 'sort')
|
||||
if [ "$EXPECTED" != "$RESULT"]; then
|
||||
echo "expected $EXPECTED but got $RESULT"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_json "-x -j -l -n --data-dir \"$TEST_DIR\"" "[{\"name\": \"Test synonyms\", \"wordcount\": \"1\"},{\"name\": \"Sample 1 test dictionary\", \"wordcount\": \"1\"},{\"name\": \"test_dict\", \"wordcount\": \"1\"}]"
|
||||
test_json "-x -j -n --data-dir \"$TEST_DIR\" foo" "[{\"dict\": \"Test synonyms\",\"word\":\"test\",\"definition\":\"\nresult of test\"}]"
|
||||
test_json "-x -j -n --data-dir \"$TEST_DIR\" foobarbaaz" "[]"
|
||||
|
||||
exit 0
|
||||
19
tests/t_only_data_dir
Executable file
19
tests/t_only_data_dir
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
SDCV="$1"
|
||||
TEST_DIR="$2"
|
||||
|
||||
unset SDCV_PAGER
|
||||
unset STARDICT_DATA_DIR
|
||||
|
||||
DICTS=$($SDCV -x -n -l --data-dir "$TEST_DIR" | tail -n +2 | wc -l)
|
||||
# the expected result:
|
||||
ACTUAL_DICTS=$(find "$TEST_DIR" -name "*.ifo" | wc -l)
|
||||
if [ $DICTS -ne $ACTUAL_DICTS ]; then
|
||||
echo "number of dictionaries in $TEST_DIR should be $ACTUAL_DICTS but was $DICTS according to sdcv"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
22
tests/t_synonyms
Executable file
22
tests/t_synonyms
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
SDCV="$1"
|
||||
TEST_DIR="$2"
|
||||
|
||||
unset SDCV_PAGER
|
||||
test_word() {
|
||||
WORD=$1
|
||||
RES=$($SDCV -n --data-dir "$TEST_DIR" -u "Test synonyms" $WORD | grep result)
|
||||
if [ "result of test" != "$RES" ]; then
|
||||
echo "synonym for $WORD should be 'result of test' but was '$RES'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_word foo
|
||||
test_word bar
|
||||
test_word test
|
||||
|
||||
exit 0
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
with open(sys.argv[1], "r") as f:
|
||||
with open(sys.argv[2], "w") as out:
|
||||
words = set([word.strip() for word in f.readlines()])
|
||||
for word in words:
|
||||
out.write(word + "\n")
|
||||
out.write(word + "\n")
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
StarDict's dict ifo file
|
||||
version=2.4.2
|
||||
wordcount=1671704
|
||||
idxfilesize=30235592
|
||||
bookname=
|
||||
date=2016.06.18
|
||||
sametypesequence=x
|
||||
3343408
tests/words_dic/words.dummy
3343408
tests/words_dic/words.dummy
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user