1

Don't use eb submodule

This commit is contained in:
Alex Yatskov 2021-01-09 14:39:52 -08:00
parent 0a9c84fd1d
commit f70b0cc19f
55 changed files with 25273 additions and 17 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.ccls-cache
zero-epwing

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "eb"]
path = eb
url = https://github.com/FooSoft/eb

143
all.c Normal file
View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2016 Alex Yatskov <alex@foosoft.net>
* Author: Alex Yatskov <alex@foosoft.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
static int eb_match_all(const char word[], const char pattern[], size_t length) {
(void) word;
(void) pattern;
(void) length;
return 0;
}
static EB_Error_Code eb_search_all(EB_Book* book, EB_Word_Code word_code) {
EB_Error_Code error_code = EB_SUCCESS;
do {
eb_lock(&book->lock);
LOG(("in: eb_search_all(book=%d)", book->code));
/* Current subbook must have been set. */
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
break;
}
/* Initialize search context. */
eb_reset_search_contexts(book);
EB_Search_Context* context = book->search_contexts;
context->code = EB_SEARCH_ALL;
context->compare_pre = eb_match_all;
context->compare_single = eb_match_all;
context->compare_group = eb_match_all;
/* Get a page number. */
switch (word_code) {
case EB_WORD_ALPHABET:
if (book->subbook_current->word_alphabet.start_page != 0) {
context->page = book->subbook_current->word_alphabet.start_page;
}
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
}
break;
case EB_WORD_KANA:
if (book->subbook_current->word_kana.start_page != 0) {
context->page = book->subbook_current->word_kana.start_page;
}
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
}
break;
case EB_WORD_OTHER:
if (book->subbook_current->word_asis.start_page != 0) {
context->page = book->subbook_current->word_asis.start_page;
}
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
}
break;
default:
error_code = EB_ERR_NO_SUCH_SEARCH;
break;
}
if (error_code != EB_SUCCESS) {
break;
}
/* Pre-search. */
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS) {
break;
}
}
while (0);
if (error_code != EB_SUCCESS) {
eb_reset_search_contexts(book);
}
LOG(("out: eb_search_all() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
int eb_have_all_search(EB_Book* book) {
eb_lock(&book->lock);
LOG(("in: eb_have_all_search(book=%d)", book->code));
int result = 0;
for (;;) {
const EB_Subbook * sb = book->subbook_current;
if (sb == NULL) {
break;
}
if (sb->word_alphabet.start_page == 0 && sb->word_asis.start_page == 0 && sb->word_kana.start_page == 0) {
break;
}
result = 1;
break;
}
LOG(("out: eb_have_all_search() = %d", result));
eb_unlock(&book->lock);
return result;
}
EB_Error_Code eb_search_all_alphabet(EB_Book* book) {
return eb_search_all(book, EB_WORD_ALPHABET);
}
EB_Error_Code eb_search_all_kana(EB_Book* book) {
return eb_search_all(book, EB_WORD_KANA);
}
EB_Error_Code eb_search_all_asis(EB_Book* book) {
return eb_search_all(book, EB_WORD_OTHER);
}

399
appendix.c Normal file
View File

@ -0,0 +1,399 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "appendix.h"
#include "build-post.h"
/*
* Appendix ID counter.
*/
static EB_Book_Code appendix_counter = 0;
/*
* Unexported functions.
*/
static EB_Error_Code eb_load_appendix_catalog(EB_Appendix *appendix);
/*
* Initialize alternation text cache in `appendix'.
*/
void
eb_initialize_alt_caches(EB_Appendix *appendix)
{
EB_Alternation_Cache *p;
int i;
LOG(("in: eb_initialize_alt_caches(appendix=%d)", (int)appendix->code));
for (i = 0, p = appendix->narrow_cache;
i < EB_MAX_ALTERNATION_CACHE; i++, p++)
p->character_number = -1;
for (i = 0, p = appendix->wide_cache;
i < EB_MAX_ALTERNATION_CACHE; i++, p++)
p->character_number = -1;
LOG(("out: eb_initialize_alt_caches()"));
}
/*
* Finalize alternation text cache in `appendix'.
*/
void
eb_finalize_alt_caches(EB_Appendix *appendix)
{
LOG(("in+out: eb_finalize_alt_caches(appendix=%d)", (int)appendix->code));
/* nothing to be done */
}
/*
* Initialize `appendix'.
*/
void
eb_initialize_appendix(EB_Appendix *appendix)
{
LOG(("in: eb_initialize_appendix()"));
appendix->code = EB_BOOK_NONE;
appendix->path = NULL;
appendix->path_length = 0;
appendix->disc_code = EB_DISC_INVALID;
appendix->subbook_count = 0;
appendix->subbooks = NULL;
appendix->subbook_current = NULL;
eb_initialize_lock(&appendix->lock);
eb_initialize_alt_caches(appendix);
LOG(("out: eb_initialize_appendix()"));
}
/*
* Finalize `appendix'.
*/
void
eb_finalize_appendix(EB_Appendix *appendix)
{
LOG(("in: eb_finalize_appendix(appendix=%d)", (int)appendix->code));
appendix->code = EB_BOOK_NONE;
if (appendix->path != NULL) {
free(appendix->path);
appendix->path = NULL;
}
appendix->path_length = 0;
appendix->disc_code = EB_DISC_INVALID;
if (appendix->subbooks != NULL) {
eb_finalize_appendix_subbooks(appendix);
free(appendix->subbooks);
appendix->subbooks = NULL;
appendix->subbook_count = 0;
}
appendix->subbook_current = NULL;
eb_finalize_lock(&appendix->lock);
eb_finalize_alt_caches(appendix);
LOG(("out: eb_finalize_appendix()"));
}
/*
* Bind `appendix' to `path'.
*/
EB_Error_Code
eb_bind_appendix(EB_Appendix *appendix, const char *path)
{
EB_Error_Code error_code;
char temporary_path[EB_MAX_PATH_LENGTH + 1];
eb_lock(&appendix->lock);
LOG(("in: eb_bind_appendix(path=%s)", path));
/*
* Reset structure members in the appendix.
*/
if (appendix->path != NULL) {
eb_finalize_appendix(appendix);
eb_initialize_appendix(appendix);
}
/*
* Assign a book code.
*/
pthread_mutex_lock(&appendix_counter_mutex);
appendix->code = appendix_counter++;
pthread_mutex_unlock(&appendix_counter_mutex);
/*
* Set path of the appendix.
* The length of the file name "path/subdir/subsubdir/file.;1" must
* be EB_MAX_PATH_LENGTH maximum.
*/
if (EB_MAX_PATH_LENGTH < strlen(path)) {
error_code = EB_ERR_TOO_LONG_FILE_NAME;
goto failed;
}
strcpy(temporary_path, path);
error_code = eb_canonicalize_path_name(temporary_path);
if (error_code != EB_SUCCESS)
goto failed;
appendix->path_length = strlen(temporary_path);
if (EB_MAX_PATH_LENGTH
< appendix->path_length + 1 + EB_MAX_RELATIVE_PATH_LENGTH) {
error_code = EB_ERR_TOO_LONG_FILE_NAME;
goto failed;
}
appendix->path = (char *)malloc(appendix->path_length + 1);
if (appendix->path == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
strcpy(appendix->path, temporary_path);
/*
* Read information from the catalog file.
*/
error_code = eb_load_appendix_catalog(appendix);
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_bind_appendix(appendix=%d) = %s", (int)appendix->code,
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_finalize_appendix(appendix);
LOG(("out: eb_bind_appendix() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Read information from the `CATALOG(S)' file in `appendix'.
* Return EB_SUCCESS, if it succeeds, error-code ohtherwise.
*/
static EB_Error_Code
eb_load_appendix_catalog(EB_Appendix *appendix)
{
EB_Error_Code error_code;
char buffer[EB_SIZE_PAGE];
char catalog_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
char catalog_path_name[EB_MAX_PATH_LENGTH + 1];
char *space;
EB_Appendix_Subbook *subbook;
size_t catalog_size;
size_t title_size;
Zio zio;
Zio_Code zio_code;
int i;
LOG(("in: eb_load_appendix_catalog(appendix=%d)", (int)appendix->code));
zio_initialize(&zio);
/*
* Find a catalog file.
*/
if (eb_find_file_name(appendix->path, "catalog", catalog_file_name)
== EB_SUCCESS) {
appendix->disc_code = EB_DISC_EB;
catalog_size = EB_SIZE_EB_CATALOG;
title_size = EB_MAX_EB_TITLE_LENGTH;
} else if (eb_find_file_name(appendix->path, "catalogs", catalog_file_name)
== EB_SUCCESS) {
appendix->disc_code = EB_DISC_EPWING;
catalog_size = EB_SIZE_EPWING_CATALOG;
title_size = EB_MAX_EPWING_TITLE_LENGTH;
} else {
error_code = EB_ERR_FAIL_OPEN_CATAPP;
goto failed;
}
eb_compose_path_name(appendix->path, catalog_file_name, catalog_path_name);
eb_path_name_zio_code(catalog_path_name, ZIO_PLAIN, &zio_code);
/*
* Open the catalog file.
*/
if (zio_open(&zio, catalog_path_name, zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_CATAPP;
goto failed;
}
/*
* Get the number of subbooks in the appendix.
*/
if (zio_read(&zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_CATAPP;
goto failed;
}
appendix->subbook_count = eb_uint2(buffer);
if (EB_MAX_SUBBOOKS < appendix->subbook_count)
appendix->subbook_count = EB_MAX_SUBBOOKS;
if (appendix->subbook_count == 0) {
error_code = EB_ERR_UNEXP_CATAPP;
goto failed;
}
/*
* Allocate memories for subbook entries.
*/
appendix->subbooks = (EB_Appendix_Subbook *)
malloc(sizeof(EB_Appendix_Subbook) * appendix->subbook_count);
if (appendix->subbooks == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
eb_initialize_appendix_subbooks(appendix);
/*
* Read subbook information.
*/
for (i = 0, subbook = appendix->subbooks; i < appendix->subbook_count;
i++, subbook++) {
/*
* Read data from the catalog file.
*/
if (zio_read(&zio, buffer, catalog_size) != catalog_size) {
error_code = EB_ERR_FAIL_READ_CAT;
goto failed;
}
/*
* Set a directory name of the subbook.
*/
strncpy(subbook->directory_name, buffer + 2 + title_size,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->directory_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
space = strchr(subbook->directory_name, ' ');
if (space != NULL)
*space = '\0';
eb_fix_directory_name(appendix->path, subbook->directory_name);
}
/*
* Close the catalog file.
*/
zio_close(&zio);
zio_finalize(&zio);
LOG(("out: eb_load_appendix_catalog() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
zio_close(&zio);
zio_finalize(&zio);
if (appendix->subbooks != NULL) {
free(appendix->subbooks);
appendix->subbooks = NULL;
}
LOG(("out: eb_load_appendix_catalog() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Examine whether `appendix' is bound or not.
*/
int
eb_is_appendix_bound(EB_Appendix *appendix)
{
int is_bound;
eb_lock(&appendix->lock);
LOG(("in: eb_is_appendix_bound(appendix=%d)", (int)appendix->code));
is_bound = (appendix->path != NULL);
LOG(("out: eb_is_appendix_bound() = %d", is_bound));
eb_unlock(&appendix->lock);
return is_bound;
}
/*
* Get the bound path of `appendix'.
*/
EB_Error_Code
eb_appendix_path(EB_Appendix *appendix, char *path)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_appendix_path(appendix=%d)", (int)appendix->code));
/*
* Check for the current status.
*/
if (appendix->path == NULL) {
error_code = EB_ERR_UNBOUND_APP;
goto failed;
}
/*
* Copy the path to `path'.
*/
strcpy(path, appendix->path);
LOG(("out: eb_appendix_path(path=%s) = %s",
path, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*path = '\0';
LOG(("out: eb_appendix_path() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}

96
appendix.h Normal file
View File

@ -0,0 +1,96 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_APPENDIX_H
#define EB_APPENDIX_H
#ifdef __cplusplus
extern "C" {
#endif
#include "eb.h"
/*
* Function declarations.
*/
/* appendix.c */
void eb_initialize_appendix(EB_Appendix *appendix);
void eb_finalize_appendix(EB_Appendix *appendix);
EB_Error_Code eb_bind_appendix(EB_Appendix *appendix, const char *path);
int eb_is_appendix_bound(EB_Appendix *appendix);
EB_Error_Code eb_appendix_path(EB_Appendix *appendix, char *path);
/* appsub.c */
EB_Error_Code eb_load_all_appendix_subbooks(EB_Appendix *appendix);
EB_Error_Code eb_appendix_subbook_list(EB_Appendix *appendix,
EB_Subbook_Code *subbook_list, int *subbook_count);
EB_Error_Code eb_appendix_subbook(EB_Appendix *appendix,
EB_Subbook_Code *subbook_code);
EB_Error_Code eb_appendix_subbook_directory(EB_Appendix *appendix,
char *directory);
EB_Error_Code eb_appendix_subbook_directory2(EB_Appendix *appendix,
EB_Subbook_Code subbook_code, char *directory);
EB_Error_Code eb_set_appendix_subbook(EB_Appendix *appendix,
EB_Subbook_Code subbook_code);
void eb_unset_appendix_subbook(EB_Appendix *appendix);
/* narwalt.c */
int eb_have_narrow_alt(EB_Appendix *appendix);
EB_Error_Code eb_narrow_alt_start(EB_Appendix *appendix, int *start);
EB_Error_Code eb_narrow_alt_end(EB_Appendix *appendix, int *end);
EB_Error_Code eb_narrow_alt_character_text(EB_Appendix *appendix,
int character_number, char *text);
EB_Error_Code eb_forward_narrow_alt_character(EB_Appendix *appendix,
int n, int *character_number);
EB_Error_Code eb_backward_narrow_alt_character(EB_Appendix *appendix,
int n, int *character_number);
/* stopcode.c */
int eb_have_stop_code(EB_Appendix *appendix);
EB_Error_Code eb_stop_code(EB_Appendix *appendix, int *);
/* widealt.c */
int eb_have_wide_alt(EB_Appendix *appendix);
EB_Error_Code eb_wide_alt_start(EB_Appendix *appendix, int *start);
EB_Error_Code eb_wide_alt_end(EB_Appendix *appendix, int *end);
EB_Error_Code eb_wide_alt_character_text(EB_Appendix *appendix,
int character_number, char *text);
EB_Error_Code eb_forward_wide_alt_character(EB_Appendix *appendix, int n,
int *character_number);
EB_Error_Code eb_backward_wide_alt_character(EB_Appendix *appendix, int n,
int *character_number);
/* for backward compatibility */
#define eb_suspend_appendix eb_unset_appendix_subbook
#define eb_initialize_all_appendix_subbooks eb_load_all_appendix_subbooks
#ifdef __cplusplus
}
#endif
#endif /* not EB_APPENDIX_H */

748
appsub.c Normal file
View File

@ -0,0 +1,748 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "appendix.h"
#include "build-post.h"
/*
* Unexported functions.
*/
static EB_Error_Code eb_load_appendix_subbook(EB_Appendix *appendix);
static EB_Error_Code eb_set_appendix_subbook_eb(EB_Appendix *appendix,
EB_Subbook_Code subbook_code);
static EB_Error_Code eb_set_appendix_subbook_epwing(EB_Appendix *appendix,
EB_Subbook_Code subbook_code);
/*
* Initialize all subbooks in `appendix'.
*/
void
eb_initialize_appendix_subbooks(EB_Appendix *appendix)
{
EB_Appendix_Subbook *subbook;
int i;
LOG(("in: eb_initialize_appendix_subbooks(appendix=%d)",
(int)appendix->code));
for (i = 0, subbook = appendix->subbooks; i < appendix->subbook_count;
i++, subbook++) {
subbook->initialized = 0;
subbook->code = i;
subbook->directory_name[0] = '\0';
subbook->data_directory_name[0] = '\0';
subbook->file_name[0] = '\0';
subbook->character_code = EB_CHARCODE_INVALID;
subbook->narrow_start = -1;
subbook->wide_start = -1;
subbook->narrow_end = -1;
subbook->wide_end = -1;
subbook->narrow_page = 0;
subbook->wide_page = 0;
subbook->stop_code0 = 0;
subbook->stop_code1 = 0;
zio_initialize(&subbook->zio);
}
LOG(("out: eb_initialize_appendix_subbooks()"));
}
/*
* Initialize subbooks in `appendix'.
*/
void
eb_finalize_appendix_subbooks(EB_Appendix *appendix)
{
EB_Appendix_Subbook *subbook;
int i;
LOG(("in: eb_finalize_appendix_subbooks(appendix=%d)",
(int)appendix->code));
for (i = 0, subbook = appendix->subbooks; i < appendix->subbook_count;
i++, subbook++) {
zio_finalize(&appendix->subbooks[i].zio);
}
LOG(("out: eb_finalize_appendix_subbooks()"));
}
/*
* Load all subbooks in `appendix'.
*/
static EB_Error_Code
eb_load_appendix_subbook(EB_Appendix *appendix)
{
EB_Error_Code error_code;
EB_Appendix_Subbook *subbook;
char buffer[16];
int stop_code_page;
int character_count;
LOG(("in: eb_load_appendix_subbook(appendix=%d)", (int)appendix->code));
subbook = appendix->subbook_current;
/*
* Check for the current status.
*/
if (subbook == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* If the subbook has already initialized, return immediately.
*/
if (subbook->initialized != 0)
goto succeeded;
/*
* Rewind the APPENDIX file.
*/
if (zio_lseek(&subbook->zio, 0, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
/*
* Set character code used in the appendix.
*/
if (zio_read(&subbook->zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
subbook->character_code = eb_uint2(buffer + 2);
/*
* Set information about alternation text of wide font.
*/
if (zio_read(&subbook->zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
character_count = eb_uint2(buffer + 12);
if (0 < character_count) {
subbook->narrow_page = eb_uint4(buffer);
subbook->narrow_start = eb_uint2(buffer + 10);
if (subbook->character_code == EB_CHARCODE_ISO8859_1) {
subbook->narrow_end = subbook->narrow_start
+ ((character_count / 0xfe) << 8) + (character_count % 0xfe)
- 1;
if (0xfe < (subbook->narrow_end & 0xff))
subbook->narrow_end += 3;
if ((subbook->narrow_start & 0xff) < 0x01
|| 0xfe < (subbook->narrow_start & 0xff)
|| subbook->narrow_start < 0x0001
|| 0x1efe < subbook->narrow_end) {
error_code = EB_ERR_UNEXP_APP;
goto failed;
}
} else {
subbook->narrow_end = subbook->narrow_start
+ ((character_count / 0x5e) << 8) + (character_count % 0x5e)
- 1;
if (0x7e < (subbook->narrow_end & 0xff))
subbook->narrow_end += 0xa3;
if ((subbook->narrow_start & 0xff) < 0x21
|| 0x7e < (subbook->narrow_start & 0xff)
|| subbook->narrow_start < 0xa121
|| 0xfe7e < subbook->narrow_end) {
error_code = EB_ERR_UNEXP_APP;
goto failed;
}
}
}
/*
* Set information about alternation text of wide font.
*/
if (zio_read(&subbook->zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
character_count = eb_uint2(buffer + 12);
if (0 < character_count) {
subbook->wide_page = eb_uint4(buffer);
subbook->wide_start = eb_uint2(buffer + 10);
if (subbook->character_code == EB_CHARCODE_ISO8859_1) {
subbook->wide_end = subbook->wide_start
+ ((character_count / 0xfe) << 8) + (character_count % 0xfe)
- 1;
if (0xfe < (subbook->wide_end & 0xff))
subbook->wide_end += 3;
if ((subbook->wide_start & 0xff) < 0x01
|| 0xfe < (subbook->wide_start & 0xff)
|| subbook->wide_start < 0x0001
|| 0x1efe < subbook->wide_end) {
error_code = EB_ERR_UNEXP_APP;
goto failed;
}
} else {
subbook->wide_end = subbook->wide_start
+ ((character_count / 0x5e) << 8) + (character_count % 0x5e)
- 1;
if (0x7e < (subbook->wide_end & 0xff))
subbook->wide_end += 0xa3;
if ((subbook->wide_start & 0xff) < 0x21
|| 0x7e < (subbook->wide_start & 0xff)
|| subbook->wide_start < 0xa121
|| 0xfe7e < subbook->wide_end) {
error_code = EB_ERR_UNEXP_APP;
goto failed;
}
}
}
/*
* Set stop-code.
*/
if (zio_read(&subbook->zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
stop_code_page = eb_uint4(buffer);
if (0 < stop_code_page) {
if (zio_lseek(&subbook->zio, ((off_t) stop_code_page - 1) * EB_SIZE_PAGE,
SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
if (zio_read(&subbook->zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
if (eb_uint2(buffer) != 0) {
subbook->stop_code0 = eb_uint2(buffer + 2);
subbook->stop_code1 = eb_uint2(buffer + 4);
}
}
/*
* Rewind the file descriptor, again.
*/
if (zio_lseek(&subbook->zio, 0, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
/*
* Initialize the alternation text cache.
*/
eb_initialize_alt_caches(appendix);
succeeded:
LOG(("out: eb_load_appendix_subbook() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_appendix_subbook() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Load all subbooks in the book.
*/
EB_Error_Code
eb_load_all_appendix_subbooks(EB_Appendix *appendix)
{
EB_Error_Code error_code;
EB_Subbook_Code current_subbook_code;
EB_Appendix_Subbook *subbook;
int i;
eb_lock(&appendix->lock);
LOG(("in: eb_load_all_appendix_subbooks(appendix=%d)",
(int)appendix->code));
/*
* The appendix must have been bound.
*/
if (appendix->path == NULL) {
error_code = EB_ERR_UNBOUND_APP;
goto failed;
}
/*
* Get the current subbook.
*/
if (appendix->subbook_current != NULL)
current_subbook_code = appendix->subbook_current->code;
else
current_subbook_code = -1;
/*
* Initialize each subbook.
*/
for (i = 0, subbook = appendix->subbooks;
i < appendix->subbook_count; i++, subbook++) {
error_code = eb_set_appendix_subbook(appendix, subbook->code);
if (error_code != EB_SUCCESS)
goto failed;
}
/*
* Restore the current subbook.
*/
if (current_subbook_code < 0)
eb_unset_appendix_subbook(appendix);
else {
error_code = eb_set_appendix_subbook(appendix, current_subbook_code);
if (error_code != EB_SUCCESS)
goto failed;
}
LOG(("out: eb_load_all_appendix_subbooks() = %s",
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_all_appendix_subbooks() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get a subbook list in `appendix'.
*/
EB_Error_Code
eb_appendix_subbook_list(EB_Appendix *appendix, EB_Subbook_Code *subbook_list,
int *subbook_count)
{
EB_Error_Code error_code;
EB_Subbook_Code *list_p;
int i;
eb_lock(&appendix->lock);
LOG(("in: eb_appendix_subbook_list(appendix=%d)", (int)appendix->code));
/*
* Check for the current status.
*/
if (appendix->path == NULL) {
error_code = EB_ERR_UNBOUND_APP;
goto failed;
}
/*
* Make a subbook list.
*/
for (i = 0, list_p = subbook_list; i < appendix->subbook_count;
i++, list_p++)
*list_p = i;
*subbook_count = appendix->subbook_count;
LOG(("out: eb_appendix_subbook_list(subbook_count=%d) = %s",
*subbook_count, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*subbook_count = 0;
LOG(("out: eb_appendix_subbook_list() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the subbook-code of the current subbook in `appendix'.
*/
EB_Error_Code
eb_appendix_subbook(EB_Appendix *appendix, EB_Subbook_Code *subbook_code)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_appendix_subbook(appendix=%d)", (int)appendix->code));
/*
* Check for the current status.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* Copy the current subbook code to `subbook_code'.
*/
*subbook_code = appendix->subbook_current->code;
LOG(("out: eb_appendix_subbook(subbook=%d) = %s", (int)*subbook_code,
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*subbook_code = EB_SUBBOOK_INVALID;
LOG(("out: eb_appendix_subbook() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the directory name of the current subbook in `appendix'.
*/
EB_Error_Code
eb_appendix_subbook_directory(EB_Appendix *appendix, char *directory)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_appendix_subbook_directory(appendix=%d)",
(int)appendix->code));
/*
* Check for the current status.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* Copy the directory name to `directory'.
*/
strcpy(directory, appendix->subbook_current->directory_name);
LOG(("out: eb_appendix_subbook_directory(directory=%s) = %s",
directory, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*directory = '\0';
LOG(("out: eb_appendix_subbook_directory() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the directory name of the subbook `subbook_code' in `appendix'.
*/
EB_Error_Code
eb_appendix_subbook_directory2(EB_Appendix *appendix,
EB_Subbook_Code subbook_code, char *directory)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_appendix_subbook_directory2(appendix=%d, subbook=%d)",
(int)appendix->code, (int)subbook_code));
/*
* Check for the current status.
*/
if (appendix->path == NULL) {
error_code = EB_ERR_UNBOUND_APP;
goto failed;
}
/*
* Check for `subbook_code'.
*/
if (subbook_code < 0 || appendix->subbook_count <= subbook_code) {
error_code = EB_ERR_NO_SUCH_APPSUB;
goto failed;
}
/*
* Copy the directory name to `directory'.
*/
strcpy(directory, (appendix->subbooks + subbook_code)->directory_name);
LOG(("out: eb_appendix_subbook_directory2(directory=%s) = %s",
directory, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*directory = '\0';
LOG(("out: eb_appendix_subbook_directory2() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Set the subbook `subbook_code' as the current subbook.
*/
EB_Error_Code
eb_set_appendix_subbook(EB_Appendix *appendix, EB_Subbook_Code subbook_code)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_set_appendix_subbook(appendix=%d, subbook=%d)",
(int)appendix->code, (int)subbook_code));
/*
* Check for the current status.
*/
if (appendix->path == NULL) {
error_code = EB_ERR_UNBOUND_APP;
goto failed;
}
/*
* Check for `subbook_code'.
*/
if (subbook_code < 0 || appendix->subbook_count <= subbook_code) {
error_code = EB_ERR_NO_SUCH_APPSUB;
goto failed;
}
/*
* If the current subbook is `subbook_code', return immediately.
* Otherwise close the current subbook and continue.
*/
if (appendix->subbook_current != NULL) {
if (appendix->subbook_current->code == subbook_code)
goto succeeded;
eb_unset_appendix_subbook(appendix);
}
/*
* Disc type specific section.
*/
if (appendix->disc_code == EB_DISC_EB)
error_code = eb_set_appendix_subbook_eb(appendix, subbook_code);
else
error_code = eb_set_appendix_subbook_epwing(appendix, subbook_code);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Load the subbook.
*/
error_code = eb_load_appendix_subbook(appendix);
if (error_code != EB_SUCCESS)
goto failed;
succeeded:
LOG(("out: eb_set_appendix_subbook() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
if (appendix->subbook_current != NULL)
zio_close(&appendix->subbook_current->zio);
appendix->subbook_current = NULL;
LOG(("out: eb_set_appendix_subbook() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* EB* specific section of eb_set_appendix_subbook().
*/
static EB_Error_Code
eb_set_appendix_subbook_eb(EB_Appendix *appendix, EB_Subbook_Code subbook_code)
{
EB_Error_Code error_code;
EB_Appendix_Subbook *subbook;
char appendix_path_name[EB_MAX_PATH_LENGTH + 1];
Zio_Code zio_code;
LOG(("in: eb_set_appendix_subbook_eb(appendix=%d, subbook=%d)",
(int)appendix->code, (int)subbook_code));
/*
* Set the current subbook.
*/
appendix->subbook_current = appendix->subbooks + subbook_code;
subbook = appendix->subbook_current;
/*
* Open an appendix file.
*/
if (eb_find_file_name2(appendix->path, subbook->directory_name,
EB_FILE_NAME_APPENDIX, subbook->file_name) != EB_SUCCESS) {
error_code = EB_ERR_FAIL_OPEN_APP;
goto failed;
}
eb_compose_path_name2(appendix->path, subbook->directory_name,
subbook->file_name, appendix_path_name);
eb_path_name_zio_code(appendix_path_name, ZIO_PLAIN, &zio_code);
if (zio_open(&subbook->zio, appendix_path_name, zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_APP;
goto failed;
}
LOG(("out: eb_set_appendix_subbook_eb() = %s",
eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_set_appendix_subbook_eb() = %s",
eb_error_string(error_code)));
return error_code;
}
/*
* EPWING specific section of eb_set_appendix_subbook().
*/
static EB_Error_Code
eb_set_appendix_subbook_epwing(EB_Appendix *appendix,
EB_Subbook_Code subbook_code)
{
EB_Error_Code error_code;
EB_Appendix_Subbook *subbook;
char appendix_path_name[EB_MAX_PATH_LENGTH + 1];
Zio_Code zio_code;
LOG(("in: eb_set_appendix_subbook_epwing(appendix=%d, subbook=%d)",
(int)appendix->code, (int)subbook_code));
/*
* Set the current subbook.
*/
appendix->subbook_current = appendix->subbooks + subbook_code;
subbook = appendix->subbook_current;
zio_initialize(&subbook->zio);
/*
* Adjust a directory name.
*/
strcpy(subbook->data_directory_name, EB_DIRECTORY_NAME_DATA);
eb_fix_directory_name2(appendix->path, subbook->directory_name,
subbook->data_directory_name);
/*
* Open an appendix file.
*/
if (eb_find_file_name3(appendix->path, subbook->directory_name,
subbook->data_directory_name, EB_FILE_NAME_FUROKU, subbook->file_name)
!= EB_SUCCESS) {
error_code = EB_ERR_FAIL_OPEN_APP;
goto failed;
}
eb_compose_path_name3(appendix->path, subbook->directory_name,
subbook->data_directory_name, subbook->file_name,
appendix_path_name);
eb_path_name_zio_code(appendix_path_name, ZIO_PLAIN, &zio_code);
if (zio_open(&subbook->zio, appendix_path_name, zio_code) < 0) {
subbook = NULL;
error_code = EB_ERR_FAIL_OPEN_APP;
goto failed;
}
LOG(("out: eb_set_appendix_subbook_epwing() = %s",
eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_set_appendix_subbook_epwing() = %s",
eb_error_string(error_code)));
return error_code;
}
/*
* Unset the current subbook.
*/
void
eb_unset_appendix_subbook(EB_Appendix *appendix)
{
eb_lock(&appendix->lock);
LOG(("in: eb_unset_appendix_subbook(appendix=%d)", (int)appendix->code));
/*
* Close a file for the current subbook.
*/
if (appendix->subbook_current != NULL) {
zio_close(&appendix->subbook_current->zio);
appendix->subbook_current = NULL;
}
LOG(("out: eb_unset_appendix_subbook()"));
eb_unlock(&appendix->lock);
}

97
bcd.c Normal file
View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Get a BCD (binary coded decimal) packed integer with 2 bytes
* from an octet stream.
*/
unsigned
eb_bcd2(const char *stream)
{
unsigned value;
const unsigned char *s = (const unsigned char *)stream;
value = ((*(s ) >> 4) & 0x0f) * 1000;
value += ((*(s ) ) & 0x0f) * 100;
value += ((*(s + 1) >> 4) & 0x0f) * 10;
value += ((*(s + 1) ) & 0x0f);
return value;
}
/*
* Get a BCD (binary coded decimal) packed integer with 4 bytes
* from an octet stream.
*/
unsigned
eb_bcd4(const char *stream)
{
unsigned value;
const unsigned char *s = (const unsigned char *)stream;
value = ((*(s ) >> 4) & 0x0f) * 10000000;
value += ((*(s ) ) & 0x0f) * 1000000;
value += ((*(s + 1) >> 4) & 0x0f) * 100000;
value += ((*(s + 1) ) & 0x0f) * 10000;
value += ((*(s + 2) >> 4) & 0x0f) * 1000;
value += ((*(s + 2) ) & 0x0f) * 100;
value += ((*(s + 3) >> 4) & 0x0f) * 10;
value += ((*(s + 3) ) & 0x0f);
return value;
}
/*
* Get a BCD (binary coded decimal) packed integer with 6 bytes
* from an octet stream.
*/
unsigned
eb_bcd6(const char *stream)
{
unsigned value;
const unsigned char *s = (const unsigned char *)stream;
value = ((*(s + 1) ) & 0x0f);
value += ((*(s + 2) >> 4) & 0x0f) * 10;
value += ((*(s + 2) ) & 0x0f) * 100;
value += ((*(s + 3) >> 4) & 0x0f) * 1000;
value += ((*(s + 3) ) & 0x0f) * 10000;
value += ((*(s + 4) >> 4) & 0x0f) * 100000;
value += ((*(s + 4) ) & 0x0f) * 1000000;
value += ((*(s + 5) >> 4) & 0x0f) * 10000000;
value += ((*(s + 5) ) & 0x0f) * 100000000;
return value;
}

1402
binary.c Normal file

File diff suppressed because it is too large Load Diff

69
binary.h Normal file
View File

@ -0,0 +1,69 @@
/* -*- C -*-
* Copyright (c) 2001-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_BINARY_H
#define EB_BINARY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include "defs.h"
/*
* Function declarations.
*/
/* binary.c */
EB_Error_Code eb_set_binary_mono_graphic(EB_Book *book,
const EB_Position *position, int width, int height);
EB_Error_Code eb_set_binary_gray_graphic(EB_Book *book,
const EB_Position *position, int width, int height);
EB_Error_Code eb_set_binary_wave(EB_Book *book,
const EB_Position *start_position, const EB_Position *end_position);
EB_Error_Code eb_set_binary_color_graphic(EB_Book *book,
const EB_Position *position);
EB_Error_Code eb_set_binary_mpeg(EB_Book *book, const unsigned int *argv);
EB_Error_Code eb_read_binary(EB_Book *book, size_t binary_max_length,
char *binary, ssize_t *binary_length);
void eb_unset_binary(EB_Book *book);
/* filename.c */
EB_Error_Code eb_compose_movie_file_name(const unsigned int *argv,
char *composed_file_name);
EB_Error_Code eb_compose_movie_path_name(EB_Book *book,
const unsigned int *argv, char *composed_path_name);
EB_Error_Code eb_decompose_movie_file_name(unsigned int *argv,
const char *composed_file_name);
#ifdef __cplusplus
}
#endif
#endif /* not EB_BINARY_H */

1362
bitmap.c Normal file

File diff suppressed because it is too large Load Diff

954
book.c Normal file
View File

@ -0,0 +1,954 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "font.h"
#include "build-post.h"
/*
* Book ID counter.
*/
static EB_Book_Code book_counter = 0;
/*
* Unexported functions.
*/
static void eb_fix_misleaded_book(EB_Book *book);
static EB_Error_Code eb_load_catalog(EB_Book *book);
static EB_Error_Code eb_load_catalog_eb(EB_Book *book,
const char *catalog_path);
static EB_Error_Code eb_load_catalog_epwing(EB_Book *book,
const char *catalog_path);
static Zio_Code eb_get_hint_zio_code(int catalog_hint_value);
static void eb_load_language(EB_Book *book);
/*
* Initialize `book'.
*/
void
eb_initialize_book(EB_Book *book)
{
LOG(("in: eb_initialize_book()"));
book->code = EB_BOOK_NONE;
book->disc_code = EB_DISC_INVALID;
book->character_code = EB_CHARCODE_INVALID;
book->path = NULL;
book->path_length = 0;
book->subbooks = NULL;
book->subbook_current = NULL;
eb_initialize_text_context(book);
eb_initialize_binary_context(book);
eb_initialize_search_contexts(book);
eb_initialize_binary_context(book);
eb_initialize_lock(&book->lock);
LOG(("out: eb_initialize_book()"));
}
/*
* Bind `book' to `path'.
*/
EB_Error_Code
eb_bind(EB_Book *book, const char *path)
{
EB_Error_Code error_code;
char temporary_path[EB_MAX_PATH_LENGTH + 1];
eb_lock(&book->lock);
LOG(("in: eb_bind(path=%s)", path));
/*
* Clear the book if the book has already been bound.
*/
if (book->path != NULL) {
eb_finalize_book(book);
eb_initialize_book(book);
}
/*
* Assign a book code.
*/
pthread_mutex_lock(&book_counter_mutex);
book->code = book_counter++;
pthread_mutex_unlock(&book_counter_mutex);
/*
* Set the path of the book.
* The length of the file name "<path>/subdir/subsubdir/file.ebz;1" must
* be EB_MAX_PATH_LENGTH maximum.
*/
if (EB_MAX_PATH_LENGTH < strlen(path)) {
error_code = EB_ERR_TOO_LONG_FILE_NAME;
goto failed;
}
strcpy(temporary_path, path);
error_code = eb_canonicalize_path_name(temporary_path);
if (error_code != EB_SUCCESS)
goto failed;
book->path_length = strlen(temporary_path);
if (EB_MAX_PATH_LENGTH
< book->path_length + 1 + EB_MAX_RELATIVE_PATH_LENGTH) {
error_code = EB_ERR_TOO_LONG_FILE_NAME;
goto failed;
}
book->path = (char *)malloc(book->path_length + 1);
if (book->path == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
strcpy(book->path, temporary_path);
/*
* Read information from the `LANGUAGE' file.
* If failed to initialize, JIS X 0208 is assumed.
*/
eb_load_language(book);
/*
* Read information from the `CATALOG(S)' file.
*/
error_code = eb_load_catalog(book);
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_bind(book=%d) = %s", (int)book->code,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_finalize_book(book);
LOG(("out: eb_bind() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Finish using `book'.
*/
void
eb_finalize_book(EB_Book *book)
{
LOG(("in: eb_finalize_book(book=%d)", (int)book->code));
eb_unset_subbook(book);
if (book->subbooks != NULL) {
eb_finalize_subbooks(book);
free(book->subbooks);
book->subbooks = NULL;
}
book->subbook_current = NULL;
eb_finalize_text_context(book);
eb_finalize_binary_context(book);
eb_finalize_search_contexts(book);
eb_finalize_binary_context(book);
eb_finalize_lock(&book->lock);
if (book->path != NULL)
free(book->path);
book->code = EB_BOOK_NONE;
book->disc_code = EB_DISC_INVALID;
book->character_code = EB_CHARCODE_INVALID;
book->path = NULL;
book->path_length = 0;
LOG(("out: eb_finalize_book()"));
}
/*
* There are some books that EB Library sets wrong character code of
* the book. They are written in JIS X 0208, but the library sets
* ISO 8859-1.
*
* We fix the character of the books. The following table lists
* titles of the first subbook in those books.
*/
static const char * const misleaded_book_table[] = {
/* SONY DataDiskMan (DD-DR1) accessories. */
"%;%s%A%e%j!\\%S%8%M%9!\\%/%i%&%s",
/* Shin Eiwa Waei Chujiten (earliest edition) */
"8&5f<R!!?71QOBCf<-E5",
/* EB Kagakugijutsu Yougo Daijiten (YRRS-048) */
"#E#B2J3X5;=QMQ8lBg<-E5",
/* Nichi-Ei-Futsu Jiten (YRRS-059) */
"#E#N#G!?#J#A#N!J!\\#F#R#E!K",
/* Japanese-English-Spanish Jiten (YRRS-060) */
"#E#N#G!?#J#A#N!J!\\#S#P#A!K",
/* Panasonic KX-EBP2 accessories. */
"%W%m%7!<%I1QOB!&OB1Q<-E5",
NULL
};
/*
* Fix chachacter-code of the book if misleaded.
*/
static void
eb_fix_misleaded_book(EB_Book *book)
{
const char * const * misleaded;
EB_Subbook *subbook;
int i;
LOG(("in: eb_fix_misleaded_book(book=%d)", (int)book->code));
for (misleaded = misleaded_book_table; *misleaded != NULL; misleaded++) {
if (strcmp(book->subbooks[0].title, *misleaded) == 0) {
book->character_code = EB_CHARCODE_JISX0208;
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
i++, subbook++) {
eb_jisx0208_to_euc(subbook->title, subbook->title);
}
break;
}
}
LOG(("out: eb_fix_misleaded_book()"));
}
/*
* Read information from the `CATALOG(S)' file in 'book'.
* Return EB_SUCCESS if it succeeds, error-code otherwise.
*/
static EB_Error_Code
eb_load_catalog(EB_Book *book)
{
EB_Error_Code error_code;
char catalog_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
char catalog_path_name[EB_MAX_PATH_LENGTH + 1];
LOG(("in: eb_load_catalog(book=%d)", (int)book->code));
/*
* Find a catalog file.
*/
if (eb_find_file_name(book->path, "catalog", catalog_file_name)
== EB_SUCCESS) {
book->disc_code = EB_DISC_EB;
} else if (eb_find_file_name(book->path, "catalogs", catalog_file_name)
== EB_SUCCESS) {
book->disc_code = EB_DISC_EPWING;
} else {
error_code = EB_ERR_FAIL_OPEN_CAT;
goto failed;
}
eb_compose_path_name(book->path, catalog_file_name, catalog_path_name);
/*
* Load the catalog file.
*/
if (book->disc_code == EB_DISC_EB)
error_code = eb_load_catalog_eb(book, catalog_path_name);
else
error_code = eb_load_catalog_epwing(book, catalog_path_name);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Fix chachacter-code of the book.
*/
eb_fix_misleaded_book(book);
LOG(("out: eb_load_catalog() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
if (book->subbooks != NULL) {
free(book->subbooks);
book->subbooks = NULL;
}
LOG(("out: eb_load_catalog() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Read information from the `CATALOG' file in 'book'. (EB)
*/
static EB_Error_Code
eb_load_catalog_eb(EB_Book *book, const char *catalog_path)
{
EB_Error_Code error_code;
char buffer[EB_SIZE_PAGE];
char *space;
EB_Subbook *subbook;
Zio zio;
Zio_Code zio_code;
int i;
LOG(("in: eb_load_catalog_eb(book=%d, catalog=%s)",
(int)book->code, catalog_path));
zio_initialize(&zio);
/*
* Open a catalog file.
*/
eb_path_name_zio_code(catalog_path, ZIO_PLAIN, &zio_code);
if (zio_open(&zio, catalog_path, zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_CAT;
goto failed;
}
/*
* Get the number of subbooks in this book.
*/
if (zio_read(&zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_CAT;
goto failed;
}
book->subbook_count = eb_uint2(buffer);
LOG(("aux: eb_load_catalog_eb(): subbook_count=%d",
book->subbook_count));
if (EB_MAX_SUBBOOKS < book->subbook_count)
book->subbook_count = EB_MAX_SUBBOOKS;
if (book->subbook_count == 0) {
error_code = EB_ERR_UNEXP_CAT;
goto failed;
}
/*
* Allocate memories for subbook entries.
*/
book->subbooks = (EB_Subbook *) malloc(sizeof(EB_Subbook)
* book->subbook_count);
if (book->subbooks == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
eb_initialize_subbooks(book);
/*
* Read information about subbook.
*/
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
i++, subbook++) {
/*
* Read data from the catalog file.
*/
if (zio_read(&zio, buffer, EB_SIZE_EB_CATALOG)
!= EB_SIZE_EB_CATALOG) {
error_code = EB_ERR_FAIL_READ_CAT;
goto failed;
}
/*
* Set a directory name.
*/
strncpy(subbook->directory_name,
buffer + 2 + EB_MAX_EB_TITLE_LENGTH,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->directory_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
space = strchr(subbook->directory_name, ' ');
if (space != NULL)
*space = '\0';
eb_fix_directory_name(book->path, subbook->directory_name);
/*
* Set an index page.
*/
subbook->index_page = 1;
/*
* Set a title. (Convert from JISX0208 to EUC JP)
*/
strncpy(subbook->title, buffer + 2, EB_MAX_EB_TITLE_LENGTH);
subbook->title[EB_MAX_EB_TITLE_LENGTH] = '\0';
if (book->character_code != EB_CHARCODE_ISO8859_1)
eb_jisx0208_to_euc(subbook->title, subbook->title);
subbook->initialized = 0;
subbook->code = i;
}
/*
* Close the catalog file.
*/
zio_close(&zio);
zio_finalize(&zio);
/*
* Fix chachacter-code of the book.
*/
eb_fix_misleaded_book(book);
LOG(("out: eb_load_catalog_eb() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
zio_close(&zio);
zio_initialize(&zio);
LOG(("out: eb_load_catalog() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Read information from the `CATALOGS' file in 'book'. (EPWING)
*/
static EB_Error_Code
eb_load_catalog_epwing(EB_Book *book, const char *catalog_path)
{
EB_Error_Code error_code;
char buffer[EB_SIZE_PAGE];
char *buffer_p;
char *space;
EB_Subbook *subbook;
EB_Font *font;
Zio zio;
Zio_Code zio_code;
int epwing_version;
int data_types;
int i, j;
LOG(("in: eb_load_catalog_epwing(book=%d, catalog=%s)",
(int)book->code, catalog_path));
zio_initialize(&zio);
/*
* Open a catalog file.
*/
eb_path_name_zio_code(catalog_path, ZIO_PLAIN, &zio_code);
if (zio_open(&zio, catalog_path, zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_CAT;
goto failed;
}
/*
* Get the number of subbooks in this book.
*/
if (zio_read(&zio, buffer, 16) != 16) {
error_code = EB_ERR_FAIL_READ_CAT;
goto failed;
}
book->subbook_count = eb_uint2(buffer);
LOG(("aux: eb_load_catalog_epwing(): subbook_count=%d",
book->subbook_count));
if (EB_MAX_SUBBOOKS < book->subbook_count)
book->subbook_count = EB_MAX_SUBBOOKS;
if (book->subbook_count == 0) {
error_code = EB_ERR_UNEXP_CAT;
goto failed;
}
epwing_version = eb_uint2(buffer + 2);
LOG(("aux: eb_load_catalog_epwing(): epwing_version=%d", epwing_version));
/*
* Allocate memories for subbook entries.
*/
book->subbooks = (EB_Subbook *) malloc(sizeof(EB_Subbook)
* book->subbook_count);
if (book->subbooks == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
eb_initialize_subbooks(book);
/*
* Read information about subbook.
*/
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
i++, subbook++) {
/*
* Read data from the catalog file.
*/
if (zio_read(&zio, buffer, EB_SIZE_EPWING_CATALOG)
!= EB_SIZE_EPWING_CATALOG) {
error_code = EB_ERR_FAIL_READ_CAT;
goto failed;
}
/*
* Set a directory name.
*/
strncpy(subbook->directory_name,
buffer + 2 + EB_MAX_EPWING_TITLE_LENGTH,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->directory_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
space = strchr(subbook->directory_name, ' ');
if (space != NULL)
*space = '\0';
eb_fix_directory_name(book->path, subbook->directory_name);
/*
* Set an index page.
*/
subbook->index_page = eb_uint2(buffer + 2 + EB_MAX_EPWING_TITLE_LENGTH
+ EB_MAX_DIRECTORY_NAME_LENGTH + 4);
/*
* Set a title. (Convert from JISX0208 to EUC JP)
*/
strncpy(subbook->title, buffer + 2, EB_MAX_EPWING_TITLE_LENGTH);
subbook->title[EB_MAX_EPWING_TITLE_LENGTH] = '\0';
if (book->character_code != EB_CHARCODE_ISO8859_1)
eb_jisx0208_to_euc(subbook->title, subbook->title);
/*
* Narrow font file names.
*/
buffer_p = buffer + 2 + EB_MAX_EPWING_TITLE_LENGTH + 50;
for (font = subbook->narrow_fonts, j = 0; j < EB_MAX_FONTS;
j++, font++) {
/*
* Skip this entry if the first character of the file name
* is not valid.
*/
if (*buffer_p == '\0' || 0x80 <= *((unsigned char *)buffer_p)) {
buffer_p += EB_MAX_DIRECTORY_NAME_LENGTH;
continue;
}
strncpy(font->file_name, buffer_p, EB_MAX_DIRECTORY_NAME_LENGTH);
font->file_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
font->font_code = j;
font->page = 1;
space = strchr(font->file_name, ' ');
if (space != NULL)
*space = '\0';
buffer_p += EB_MAX_DIRECTORY_NAME_LENGTH;
}
/*
* Wide font file names.
*/
buffer_p = buffer + 2 + EB_MAX_EPWING_TITLE_LENGTH + 18;
for (font = subbook->wide_fonts, j = 0; j < EB_MAX_FONTS;
j++, font++) {
/*
* Skip this entry if the first character of the file name
* is not valid.
*/
if (*buffer_p == '\0' || 0x80 <= *((unsigned char *)buffer_p)) {
buffer_p += EB_MAX_DIRECTORY_NAME_LENGTH;
continue;
}
strncpy(font->file_name, buffer_p, EB_MAX_DIRECTORY_NAME_LENGTH);
font->file_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
font->font_code = j;
font->page = 1;
space = strchr(font->file_name, ' ');
if (space != NULL)
*space = '\0';
buffer_p += EB_MAX_DIRECTORY_NAME_LENGTH;
}
subbook->initialized = 0;
subbook->code = i;
}
/*
* Set default file names and compression types.
*/
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
i++, subbook++) {
strcpy(subbook->text_file_name, EB_FILE_NAME_HONMON);
strcpy(subbook->graphic_file_name, EB_FILE_NAME_HONMON);
strcpy(subbook->sound_file_name, EB_FILE_NAME_HONMON);
subbook->text_hint_zio_code = ZIO_PLAIN;
subbook->graphic_hint_zio_code = ZIO_PLAIN;
subbook->sound_hint_zio_code = ZIO_PLAIN;
}
if (epwing_version == 1)
goto succeeded;
/*
* Read extra information about subbook.
*/
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
i++, subbook++) {
/*
* Read data from the catalog file.
*
* We don't complain about unexpected EOF. In that case, we
* return EB_SUCCESS.
*/
ssize_t read_result = zio_read(&zio, buffer, EB_SIZE_EPWING_CATALOG);
if (read_result < 0) {
error_code = EB_ERR_FAIL_READ_CAT;
goto failed;
} else if (read_result != EB_SIZE_EPWING_CATALOG) {
break;
}
if (*(buffer + 4) == '\0')
continue;
/*
* Set a text file name and its compression hint.
*/
*(subbook->text_file_name) = '\0';
strncpy(subbook->text_file_name,
buffer + 4, EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->text_file_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
space = strchr(subbook->text_file_name, ' ');
if (space != NULL)
*space = '\0';
subbook->text_hint_zio_code
= eb_get_hint_zio_code(eb_uint1(buffer + 55));
if (subbook->text_hint_zio_code == ZIO_INVALID) {
error_code = EB_ERR_UNEXP_CAT;
goto failed;
}
data_types = eb_uint2(buffer + 41);
/*
* Set a graphic file name and its compression hint.
*/
*(subbook->graphic_file_name) = '\0';
if ((data_types & 0x03) == 0x02) {
strncpy(subbook->graphic_file_name, buffer + 44,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->graphic_hint_zio_code
= eb_get_hint_zio_code(eb_uint1(buffer + 54));
} else if (((data_types >> 8) & 0x03) == 0x02) {
strncpy(subbook->graphic_file_name, buffer + 56,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->graphic_hint_zio_code
= eb_get_hint_zio_code(eb_uint1(buffer + 53));
}
subbook->graphic_file_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
space = strchr(subbook->graphic_file_name, ' ');
if (space != NULL)
*space = '\0';
if (*(subbook->graphic_file_name) == '\0') {
strcpy(subbook->graphic_file_name, subbook->text_file_name);
subbook->graphic_hint_zio_code = subbook->text_hint_zio_code;
}
if (subbook->graphic_hint_zio_code == ZIO_INVALID) {
error_code = EB_ERR_UNEXP_CAT;
goto failed;
}
/*
* Set a sound file name and its compression hint.
*/
*(subbook->sound_file_name) = '\0';
if ((data_types & 0x03) == 0x01) {
strncpy(subbook->sound_file_name, buffer + 44,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->sound_hint_zio_code
= eb_get_hint_zio_code(eb_uint1(buffer + 54));
} else if (((data_types >> 8) & 0x03) == 0x01) {
strncpy(subbook->sound_file_name, buffer + 56,
EB_MAX_DIRECTORY_NAME_LENGTH);
subbook->sound_hint_zio_code
= eb_get_hint_zio_code(eb_uint1(buffer + 53));
}
subbook->sound_file_name[EB_MAX_DIRECTORY_NAME_LENGTH] = '\0';
space = strchr(subbook->sound_file_name, ' ');
if (space != NULL)
*space = '\0';
if (*(subbook->sound_file_name) == '\0') {
strcpy(subbook->sound_file_name, subbook->text_file_name);
subbook->sound_hint_zio_code = subbook->text_hint_zio_code;
}
if (subbook->sound_hint_zio_code == ZIO_INVALID) {
error_code = EB_ERR_UNEXP_CAT;
goto failed;
}
}
/*
* Close the catalog file.
*/
succeeded:
zio_close(&zio);
zio_finalize(&zio);
/*
* Fix chachacter-code of the book.
*/
eb_fix_misleaded_book(book);
LOG(("out: eb_load_catalog_epwing() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
zio_close(&zio);
zio_initialize(&zio);
LOG(("out: eb_load_catalog_epwing() = %s", eb_error_string(error_code)));
return error_code;
}
static Zio_Code
eb_get_hint_zio_code(int catalog_hint_value)
{
switch (catalog_hint_value) {
case 0x00:
return ZIO_PLAIN;
break;
case 0x11:
return ZIO_EPWING;
break;
case 0x12:
return ZIO_EPWING6;
break;
}
return ZIO_INVALID;
}
/*
* Read information from the `LANGUAGE' file in `book'.
*/
static void
eb_load_language(EB_Book *book)
{
Zio zio;
Zio_Code zio_code;
char language_path_name[EB_MAX_PATH_LENGTH + 1];
char language_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
char buffer[16];
LOG(("in: eb_load_language(book=%d)", (int)book->code));
zio_initialize(&zio);
book->character_code = EB_CHARCODE_JISX0208;
/*
* Open the language file.
*/
if (eb_find_file_name(book->path, "language", language_file_name)
!= EB_SUCCESS)
goto failed;
eb_compose_path_name(book->path, language_file_name, language_path_name);
eb_path_name_zio_code(language_path_name, ZIO_PLAIN, &zio_code);
if (zio_open(&zio, language_path_name, zio_code) < 0)
goto failed;
/*
* Get a character code of the book, and get the number of langueages
* in the file.
*/
if (zio_read(&zio, buffer, 16) != 16)
goto failed;
book->character_code = eb_uint2(buffer);
if (book->character_code != EB_CHARCODE_ISO8859_1
&& book->character_code != EB_CHARCODE_JISX0208
&& book->character_code != EB_CHARCODE_JISX0208_GB2312) {
goto failed;
}
zio_close(&zio);
LOG(("out: eb_load_language()"));
return;
/*
* An error occurs...
*/
failed:
zio_close(&zio);
LOG(("out: eb_load_language()"));
}
/*
* Test whether `book' is bound.
*/
int
eb_is_bound(EB_Book *book)
{
int is_bound;
eb_lock(&book->lock);
LOG(("in: eb_is_bound(book=%d)", (int)book->code));
/*
* Check for the current status.
*/
is_bound = (book->path != NULL);
LOG(("out: eb_is_bound() = %d", is_bound));
eb_unlock(&book->lock);
return is_bound;
}
/*
* Return the bound path of `book'.
*/
EB_Error_Code
eb_path(EB_Book *book, char *path)
{
EB_Error_Code error_code;
eb_lock(&book->lock);
LOG(("in: eb_path(book=%d)", (int)book->code));
/*
* Check for the current status.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Copy the path to `path'.
*/
strcpy(path, book->path);
LOG(("out: eb_path(path=%s) = %s", path, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*path = '\0';
LOG(("out: eb_path() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Inspect a disc type.
*/
EB_Error_Code
eb_disc_type(EB_Book *book, EB_Disc_Code *disc_code)
{
EB_Error_Code error_code;
eb_lock(&book->lock);
LOG(("in: eb_disc_type(book=%d)", (int)book->code));
/*
* Check for the current status.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Copy the disc code to `disc_code'.
*/
*disc_code = book->disc_code;
LOG(("out: eb_disc_type(disc_code=%d) = %s", (int)*disc_code,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*disc_code = EB_DISC_INVALID;
LOG(("out: eb_disc_type() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Inspect a character code used in the book.
*/
EB_Error_Code
eb_character_code(EB_Book *book, EB_Character_Code *character_code)
{
EB_Error_Code error_code;
eb_lock(&book->lock);
LOG(("in: eb_character_code(book=%d)", (int)book->code));
/*
* Check for the current status.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Copy the character code to `character_code'.
*/
*character_code = book->character_code;
LOG(("out: eb_character_code(character_code=%d) = %s",
(int)*character_code, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_code = EB_CHARCODE_INVALID;
LOG(("out: eb_character_code() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

264
booklist.c Normal file
View File

@ -0,0 +1,264 @@
/*
* Copyright (c) 2003-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Initial value of `max_entry_count' in `EB_BookList'.
*/
#define EB_INITIAL_BOOKLIST_MAX_ENTRY_COUNT 16
/*
* BookList ID counter.
*/
static EB_Book_Code booklist_counter = 0;
/*
* Initialize a book list.
*/
void
eb_initialize_booklist(EB_BookList *booklist)
{
LOG(("in: eb_initialize_booklist()"));
booklist->entry_count = 0;
booklist->max_entry_count = 0;
booklist->entries = NULL;
eb_initialize_lock(&booklist->lock);
LOG(("out: eb_initialize_booklist()"));
}
/*
* Finalize a book list.
*/
void
eb_finalize_booklist(EB_BookList *booklist)
{
int i;
LOG(("in: eb_finalize_booklist()"));
if (booklist->entries != NULL) {
for (i = 0; i < booklist->entry_count; i++) {
free(booklist->entries[i].name);
free(booklist->entries[i].title);
}
free(booklist->entries);
booklist->entries = NULL;
}
booklist->entry_count = 0;
booklist->max_entry_count = 0;
LOG(("out: eb_finalize_booklist()"));
}
/*
* Add a book entry to `booklist'.
*/
EB_Error_Code
eb_booklist_add_book(EB_BookList *booklist, const char *name,
const char *title)
{
int new_max_entry_count;
EB_BookList_Entry *new_entries;
char *new_name = NULL;
char *new_title = NULL;
EB_Error_Code error_code;
LOG(("in: eb_booklist_add_book(name=%s, title=%s)", name, title));
if (booklist->entry_count == booklist->max_entry_count) {
if (booklist->max_entry_count == 0) {
new_max_entry_count = EB_INITIAL_BOOKLIST_MAX_ENTRY_COUNT;
new_entries = (EB_BookList_Entry *)
malloc(sizeof(EB_BookList_Entry) * new_max_entry_count);
} else {
new_max_entry_count = booklist->max_entry_count * 2;
new_entries = (EB_BookList_Entry *)realloc(booklist->entries,
sizeof(EB_BookList_Entry) * new_max_entry_count);
}
if (new_entries == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
booklist->max_entry_count = new_max_entry_count;
booklist->entries = new_entries;
}
new_name = (char *)malloc(strlen(name) + 1);
if (new_name == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
strcpy(new_name, name);
new_title = (char *)malloc(strlen(title) + 1);
if (new_title == NULL) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
strcpy(new_title, title);
booklist->entries[booklist->entry_count].name = new_name;
booklist->entries[booklist->entry_count].title = new_title;
booklist->entry_count++;
LOG(("out: eb_booklist_add_book() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
if (new_name != NULL)
free(new_name);
if (new_title != NULL)
free(new_title);
LOG(("out: eb_booklist_book_add() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Return the number of books in `booklist'.
*/
EB_Error_Code
eb_booklist_book_count(EB_BookList *booklist, int *book_count)
{
EB_Error_Code error_code;
eb_lock(&booklist->lock);
LOG(("in: eb_booklist_book_count(booklist=%d)", (int)booklist->code));
if (booklist->entries == NULL) {
error_code = EB_ERR_UNBOUND_BOOKLIST;
goto failed;
}
*book_count = booklist->entry_count;
LOG(("out: eb_booklist_book_count(count=%d) = %s", *book_count,
eb_error_string(EB_SUCCESS)));
eb_unlock(&booklist->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_booklist_book_count() = %s", eb_error_string(error_code)));
eb_unlock(&booklist->lock);
return error_code;
}
/*
* Return title of a book entry in `booklist'.
*/
EB_Error_Code
eb_booklist_book_name(EB_BookList *booklist, int book_index, char **book_name)
{
EB_Error_Code error_code;
eb_lock(&booklist->lock);
LOG(("in: eb_booklist_book_name(booklist=%d,index=%d)",
(int)booklist->code, book_index));
if (booklist->entries == NULL) {
error_code = EB_ERR_UNBOUND_BOOKLIST;
goto failed;
}
if (book_index < 0 || booklist->entry_count <= book_index) {
error_code = EB_ERR_NO_SUCH_BOOK;
goto failed;
}
*book_name = booklist->entries[book_index].name;
LOG(("out: eb_booklist_book_name(*book_name=%s) = %s",
(*book_name == NULL) ? "NULL" : *book_name,
eb_error_string(EB_SUCCESS)));
eb_unlock(&booklist->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_booklist_book_name() = %s", eb_error_string(error_code)));
eb_unlock(&booklist->lock);
return error_code;
}
/*
* Return name of a book entry in `booklist'.
*/
EB_Error_Code
eb_booklist_book_title(EB_BookList *booklist, int book_index,
char **book_title)
{
EB_Error_Code error_code;
eb_lock(&booklist->lock);
LOG(("in: eb_booklist_book_title(booklist=%d,index=%d)",
(int)booklist->code, book_index));
if (booklist->entries == NULL) {
error_code = EB_ERR_UNBOUND_BOOKLIST;
goto failed;
}
if (book_index < 0 || booklist->entry_count <= book_index) {
error_code = EB_ERR_NO_SUCH_BOOK;
goto failed;
}
*book_title = booklist->entries[book_index].title;
LOG(("out: eb_booklist_book_title(*book_title=%s) = %s",
(*book_title == NULL) ? "NULL" : *book_title,
eb_error_string(EB_SUCCESS)));
eb_unlock(&booklist->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_booklist_book_title() = %s", eb_error_string(error_code)));
eb_unlock(&booklist->lock);
return error_code;
}

56
booklist.h Normal file
View File

@ -0,0 +1,56 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_BOOKLIST_H
#define EB_BOOKLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include "eb.h"
/*
* Function declarations.
*/
/* booklist.c */
void eb_initialize_booklist(EB_BookList *booklist);
void eb_finalize_booklist(EB_BookList *booklist);
EB_Error_Code eb_bind_booklist(EB_BookList *booklist, const char *path);
EB_Error_Code eb_booklist_book_count(EB_BookList *booklist, int *book_count);
EB_Error_Code eb_booklist_book_name(EB_BookList *booklist, int book_index,
char **book_name);
EB_Error_Code eb_booklist_book_title(EB_BookList *booklist, int book_index,
char **book_title);
#ifdef __cplusplus
}
#endif
#endif /* not EB_BOOKLIST_H */

356
build-post.h Normal file
View File

@ -0,0 +1,356 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_BUILD_POST_H
#define EB_BUILD_POST_H
#include "defs.h"
/*
* Text domain name.
*/
#define EB_TEXT_DOMAIN_NAME "eb"
/*
* Locale directory.
*/
#ifndef WIN32
#define EB_LOCALEDIR "@localedir@"
#else
#define EB_LOCALEDIR localedir()
#endif
/*
* Data size of a book entry in a catalog file.
*/
#define EB_SIZE_EB_CATALOG 40
#define EB_SIZE_EPWING_CATALOG 164
/*
* Maximum number of search titles.
*/
#define EB_MAX_SEARCH_TITLES 14
/*
* File names.
*/
#define EB_FILE_NAME_START "start"
#define EB_FILE_NAME_HONMON "honmon"
#define EB_FILE_NAME_FUROKU "furoku"
#define EB_FILE_NAME_APPENDIX "appendix"
/*
* Directory names.
*/
#define EB_DIRECTORY_NAME_DATA "data"
#define EB_DIRECTORY_NAME_GAIJI "gaiji"
#define EB_DIRECTORY_NAME_STREAM "stream"
#define EB_DIRECTORY_NAME_MOVIE "movie"
/*
* Search word types.
*/
#define EB_WORD_ALPHABET 0
#define EB_WORD_KANA 1
#define EB_WORD_OTHER 2
#define EB_WORD_INVALID -1
/*
* Index Style flags.
*/
#define EB_INDEX_STYLE_CONVERT 0
#define EB_INDEX_STYLE_ASIS 1
#define EB_INDEX_STYLE_REVERSED_CONVERT 2
#define EB_INDEX_STYLE_DELETE 2
/*
* Text content currently read.
*/
#define EB_TEXT_MAIN_TEXT 1
#define EB_TEXT_HEADING 2
#define EB_TEXT_RAWTEXT 3
#define EB_TEXT_OPTIONAL_TEXT 4
#define EB_TEXT_SEEKED 0
#define EB_TEXT_INVALID -1
/*
* Search method currently processed.
*/
#define EB_SEARCH_EXACTWORD 0
#define EB_SEARCH_WORD 1
#define EB_SEARCH_ENDWORD 2
#define EB_SEARCH_KEYWORD 3
#define EB_SEARCH_MULTI 4
#define EB_SEARCH_CROSS 5
#define EB_SEARCH_ALL 6
#define EB_SEARCH_NONE -1
/*
* Arrangement style of entries in a search index page.
*/
#define EB_ARRANGE_FIXED 0
#define EB_ARRANGE_VARIABLE 1
#define EB_ARRANGE_INVALID -1
/*
* Binary data types.
*/
#define EB_BINARY_MONO_GRAPHIC 0
#define EB_BINARY_COLOR_GRAPHIC 1
#define EB_BINARY_WAVE 2
#define EB_BINARY_MPEG 3
#define EB_BINARY_GRAY_GRAPHIC 4
#define EB_BINARY_INVALID -1
/*
* Text-stop status.
*/
#define EB_TEXT_STATUS_CONTINUED 0
#define EB_TEXT_STATUS_SOFT_STOP 1
#define EB_TEXT_STATUS_HARD_STOP 2
/*
* The maximum index depth of search indexes.
*/
#define EB_MAX_INDEX_DEPTH 6
/*
* The maximum length of path name relative to top directory of a CD-ROM
* book. An example of the longest relative path is:
*
* "subdir01/subdir02/filename.ebz;1"
*/
#define EB_MAX_RELATIVE_PATH_LENGTH \
(EB_MAX_DIRECTORY_NAME_LENGTH + 1 \
+ EB_MAX_DIRECTORY_NAME_LENGTH + 1 \
+ EB_MAX_FILE_NAME_LENGTH)
/*
* The environment variable name to enable/disable debug messages.
*/
#define EB_DEBUG_ENVIRONMENT_VARIABLE "EB_DEBUG"
/*
* Trace log macro.
*/
#define LOG(x) do {if (eb_log_flag) eb_log x;} while (0)
/*
* Get an unsigned value from an octet stream buffer.
*/
#define eb_uint1(p) (*(const unsigned char *)(p))
#define eb_uint2(p) ((*(const unsigned char *)(p) << 8) \
+ (*(const unsigned char *)((p) + 1)))
#define eb_uint3(p) ((*(const unsigned char *)(p) << 16) \
+ (*(const unsigned char *)((p) + 1) << 8) \
+ (*(const unsigned char *)((p) + 2)))
#define eb_uint4(p) ((*(const unsigned char *)(p) << 24) \
+ (*(const unsigned char *)((p) + 1) << 16) \
+ (*(const unsigned char *)((p) + 2) << 8) \
+ (*(const unsigned char *)((p) + 3)))
#define eb_uint4_le(p) ((*(const unsigned char *)(p)) \
+ (*(const unsigned char *)((p) + 1) << 8) \
+ (*(const unsigned char *)((p) + 2) << 16) \
+ (*(const unsigned char *)((p) + 3) << 24))
/*
* Test whether `off_t' represents a large integer.
*/
#define off_t_is_large \
((((off_t) 1 << 41) + ((off_t) 1 << 40) + 1) % 9999991 == 7852006)
/*
* External variable declarations.
*/
/* log.c */
extern int eb_log_flag;
/* hook.c */
extern EB_Hookset eb_default_hookset;
/*
* Function declarations.
*/
/* appendix.c */
void eb_initialize_alt_caches(EB_Appendix *appendix);
void eb_finalize_alt_caches(EB_Appendix *appendix);
/* appsub.c */
void eb_initialize_appendix_subbooks(EB_Appendix *appendix);
void eb_finalize_appendix_subbooks(EB_Appendix *appendix);
/* bcd.c */
unsigned eb_bcd2(const char *stream);
unsigned eb_bcd4(const char *stream);
unsigned eb_bcd6(const char *stream);
/* binary.c */
void eb_initialize_binary_context(EB_Book *book);
void eb_reset_binary_context(EB_Book *book);
void eb_finalize_binary_context(EB_Book *book);
/* booklist.c */
EB_Error_Code eb_booklist_add_book(EB_BookList *booklist, const char *name,
const char *title);
/* filename.c */
EB_Error_Code eb_canonicalize_path_name(char *path_name);
void eb_canonicalize_file_name(char *file_name);
EB_Error_Code eb_fix_directory_name(const char *path, char *directory_name);
EB_Error_Code eb_fix_directory_name2(const char *path,
const char *directory_name, char *sub_directory_name);
void eb_fix_path_name_suffix(char *path_name, const char *suffix);
EB_Error_Code eb_find_file_name(const char *path_name,
const char *target_file_name, char *found_file_name);
EB_Error_Code eb_find_file_name2(const char *path_name,
const char *sub_directory_name, const char *target_file_name,
char *found_file_name);
EB_Error_Code eb_find_file_name3(const char *path_name,
const char *sub_directory_name, const char *sub2_directory_name,
const char *target_file_name, char *found_file_name);
void eb_compose_path_name(const char *path_name, const char *file_name,
char *composed_path_name);
void eb_compose_path_name2(const char *path_name,
const char *sub_directory_name, const char *file_name,
char *composed_path_name);
void eb_compose_path_name3(const char *path_name,
const char *sub_directory_name, const char *sub2_directory_name,
const char *file_name, char *composed_path_name);
void eb_path_name_zio_code(const char *path_name, Zio_Code default_zio_code,
Zio_Code *zio_code);
/* font.c */
void eb_initialize_fonts(EB_Book *book);
void eb_load_font_headers(EB_Book *book);
void eb_finalize_fonts(EB_Book *book);
/* hook.c */
void eb_initialize_default_hookset(void);
/* jacode.c */
void eb_jisx0208_to_euc(char *out_string, const char *in_string);
void eb_sjis_to_euc(char *out_string, const char *in_string);
/* lock.c */
#ifdef ENABLE_PTHREAD
void eb_initialize_lock(EB_Lock *lock);
void eb_finalize_lock(EB_Lock *lock);
void eb_lock(EB_Lock *lock);
void eb_unlock(EB_Lock *lock);
#else /* not ENABLE_PTHREAD */
#define eb_lock(x)
#define eb_unlock(x)
#define eb_initialize_lock(x)
#define eb_finalize_lock(x)
#endif /* not ENABLE_PTHREAD */
/* log.c */
void eb_initialize_log(void);
const char *eb_quoted_stream(const char *stream, size_t stream_length);
const char *eb_quoted_string(const char *string);
/* match.c */
int eb_match_word(const char *word, const char *pattern, size_t length);
int eb_pre_match_word(const char *word, const char *pattern, size_t length);
int eb_exact_match_word_jis(const char *word, const char *pattern,
size_t length);
int eb_exact_pre_match_word_jis(const char *word, const char *pattern,
size_t length);
int eb_exact_match_word_latin(const char *word, const char *pattern,
size_t length);
int eb_exact_pre_match_word_latin(const char *word, const char *pattern,
size_t);
int eb_match_word_kana_single(const char *word, const char *pattern,
size_t length);
int eb_match_word_kana_group(const char *word, const char *pattern,
size_t length);
int eb_exact_match_word_kana_single(const char *word, const char *pattern,
size_t length);
int eb_exact_match_word_kana_group(const char *word, const char *pattern,
size_t length);
/* message.c */
EB_Error_Code eb_initialize_messages(EB_Book *book);
/* multi.c */
EB_Error_Code eb_load_multi_searches(EB_Book *book);
EB_Error_Code eb_load_multi_titles(EB_Book *book);
/* narwfont.c */
EB_Error_Code eb_open_narrow_font_file(EB_Book *book, EB_Font_Code font_code);
EB_Error_Code eb_load_narrow_font_header(EB_Book *book,
EB_Font_Code font_code);
EB_Error_Code eb_load_narrow_font_glyphs(EB_Book *book,
EB_Font_Code font_code);
/* search.c */
void eb_initialize_search_contexts(EB_Book *book);
void eb_finalize_search_contexts(EB_Book *book);
void eb_reset_search_contexts(EB_Book *book);
void eb_initialize_search(EB_Search *search);
void eb_finalize_search(EB_Search *search);
void eb_initialize_searches(EB_Book *book);
void eb_finalize_searches(EB_Book *book);
EB_Error_Code eb_presearch_word(EB_Book *book, EB_Search_Context *context);
/* setword.c */
EB_Error_Code eb_set_word(EB_Book *book, const char *input_word, char *word,
char *canonicalized_word, EB_Word_Code *word_code);
EB_Error_Code eb_set_endword(EB_Book *book, const char *input_word, char *word,
char *canonicalized_word, EB_Word_Code *word_code);
EB_Error_Code eb_set_keyword(EB_Book *book, const char *input_word, char *word,
char *canonicalized_word, EB_Word_Code *word_code);
EB_Error_Code eb_set_multiword(EB_Book *book, EB_Multi_Search_Code multi_id,
EB_Multi_Entry_Code entry_id, const char *input_word, char *word,
char *canonicalized_word, EB_Word_Code *word_code);
/* subbook.c */
void eb_initialize_subbooks(EB_Book *book);
void eb_finalize_subbooks(EB_Book *book);
/* text.c */
void eb_initialize_text_context(EB_Book *book);
void eb_finalize_text_context(EB_Book *book);
void eb_reset_text_context(EB_Book *book);
void eb_invalidate_text_context(EB_Book *book);
EB_Error_Code eb_forward_heading(EB_Book *book);
/* widefont.c */
EB_Error_Code eb_open_wide_font_file(EB_Book *book, EB_Font_Code font_code);
EB_Error_Code eb_load_wide_font_header(EB_Book *book, EB_Font_Code font_code);
EB_Error_Code eb_load_wide_font_glyphs(EB_Book *book, EB_Font_Code font_code);
/* strcasecmp.c */
int eb_strcasecmp(const char *string1, const char *string2);
int eb_strncasecmp(const char *string1, const char *string2, size_t n);
#endif /* not EB_BUILD_POST_H */

108
build-pre.h Normal file
View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2000-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_BUILD_PRE_H
#define EB_BUILD_PRE_H
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/time.h>
/*
* Mutual exclusion lock of Pthreads.
*/
#ifndef ENABLE_PTHREAD
#define pthread_mutex_lock(m)
#define pthread_mutex_unlock(m)
#endif
/*
* stat() macros.
*/
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
/*
* Flags for open().
*/
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*
* Character type tests and conversions.
*/
#define ASCII_ISDIGIT(c) ('0' <= (c) && (c) <= '9')
#define ASCII_ISUPPER(c) ('A' <= (c) && (c) <= 'Z')
#define ASCII_ISLOWER(c) ('a' <= (c) && (c) <= 'z')
#define ASCII_ISALPHA(c) \
(ASCII_ISUPPER(c) || ASCII_ISLOWER(c))
#define ASCII_ISALNUM(c) \
(ASCII_ISUPPER(c) || ASCII_ISLOWER(c) || ASCII_ISDIGIT(c))
#define ASCII_ISXDIGIT(c) \
(ASCII_ISDIGIT(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
#define ASCII_TOUPPER(c) (('a' <= (c) && (c) <= 'z') ? (c) - 0x20 : (c))
#define ASCII_TOLOWER(c) (('A' <= (c) && (c) <= 'Z') ? (c) + 0x20 : (c))
/*
* Tricks for gettext.
*/
#ifdef ENABLE_NLS
#define _(string) gettext(string)
#ifdef gettext_noop
#define N_(string) gettext_noop(string)
#else
#define N_(string) (string)
#endif
#else
#define _(string) (string)
#define N_(string) (string)
#endif
/*
* Fake missing function names.
*/
#ifndef HAVE_STRCASECMP
#define strcasecmp eb_strcasecmp
#define strncasecmp eb_strncasecmp
#endif
#endif /* EB_BUILD_PRE_H */

View File

@ -1,7 +0,0 @@
#!/bin/bash
pushd eb
./configure --disable-shared --disable-ebnet --disable-nls
pushd eb
make
popd
popd

119
copyright.c Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' have a copyright
* notice or not.
*/
int
eb_have_copyright(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_copyright(book=%d)", (int)book->code));
/*
* Check for the current status.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* Check for the index page of copyright notice.
*/
if (book->subbook_current->copyright.start_page == 0)
goto failed;
LOG(("out: eb_have_copyright() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_copyright() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Get a position of copyright notice.
*/
EB_Error_Code
eb_copyright(EB_Book *book, EB_Position *position)
{
EB_Error_Code error_code;
int page;
eb_lock(&book->lock);
LOG(("in: eb_copyright(book=%d)", (int)book->code));
/*
* Check for the current status.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check for the page number of COPYRIGHT NOTICE.
*/
page = book->subbook_current->copyright.start_page;
if (page == 0) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Copy the position to `position'.
*/
position->page = page;
position->offset = 0;
LOG(("out: eb_copyright(position={%d,%d}) = %s",
position->page, position->offset, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_copyright() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

188
cross.c Normal file
View File

@ -0,0 +1,188 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' supports `KEYWORD SEARCH'
* or not.
*/
int
eb_have_cross_search(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_cross_search(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
if (book->subbook_current->cross.start_page == 0)
goto failed;
LOG(("out: eb_have_cross_search() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_cross_search() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Keyword search.
*/
EB_Error_Code
eb_search_cross(EB_Book *book, const char * const input_words[])
{
EB_Error_Code error_code;
EB_Search_Context *context;
EB_Word_Code word_code;
int word_count;
int i;
/*
* Lock the book.
*/
eb_lock(&book->lock);
LOG(("in: eb_search_cross(book=%d, input_words=[below])",
(int)book->code));
if (eb_log_flag) {
for (i = 0; i < EB_MAX_KEYWORDS && input_words[i] != NULL; i++) {
LOG((" input_words[%d]=%s", i,
eb_quoted_string(input_words[i])));
}
LOG((" input_words[%d]=NULL", i));
}
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check whether the current subbook has cross search.
*/
if (book->subbook_current->cross.start_page == 0) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Attach a search context for each word, and pre-search the word.
*/
eb_reset_search_contexts(book);
word_count = 0;
for (i = 0; i < EB_MAX_KEYWORDS; i++) {
if (input_words[i] == NULL)
break;
/*
* Initialize search context.
*/
context = book->search_contexts + word_count;
context->code = EB_SEARCH_CROSS;
/*
* Choose comparison functions.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word;
} else {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word_kana_group;
}
context->page = book->subbook_current->cross.start_page;
/*
* Make a fixed word and a canonicalized word to search from
* `input_words[i]'.
*/
error_code = eb_set_keyword(book, input_words[i], context->word,
context->canonicalized_word, &word_code);
if (error_code == EB_ERR_EMPTY_WORD)
continue;
else if (error_code != EB_SUCCESS)
goto failed;
/*
* Pre-search.
*/
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS)
goto failed;
word_count++;
}
if (word_count == 0) {
error_code = EB_ERR_NO_WORD;
goto failed;
} else if (EB_MAX_KEYWORDS <= i && input_words[i] != NULL) {
error_code = EB_ERR_TOO_MANY_WORDS;
goto failed;
}
/*
* Set `EB_SEARCH_NONE' to the rest unused search context.
*/
for (i = word_count; i < EB_MAX_KEYWORDS; i++)
(book->search_contexts + i)->code = EB_SEARCH_NONE;
LOG(("out: eb_search_cross() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_reset_search_contexts(book);
LOG(("out: eb_search_cross() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

1006
defs.h Normal file

File diff suppressed because it is too large Load Diff

1
eb

@ -1 +0,0 @@
Subproject commit c9d1015f9ec4fdc3936f8d3905ccb7b1145eb1cf

76
eb.c Normal file
View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2000-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Initialize the library.
*/
EB_Error_Code
eb_initialize_library(void)
{
EB_Error_Code error_code;
eb_initialize_log();
LOG(("in: eb_initialize_library()"));
eb_initialize_default_hookset();
if (zio_initialize_library() < 0) {
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
}
LOG(("out: eb_initialize_library() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_initialize_library() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Finalize the library.
*/
void
eb_finalize_library(void)
{
LOG(("in: eb_finalize_library()"));
zio_finalize_library();
LOG(("out: eb_finalize_library()"));
}

157
eb.h Normal file
View File

@ -0,0 +1,157 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_EB_H
#define EB_EB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "defs.h"
#include <stdarg.h>
/*
* Function declarations.
*/
/* book.c */
void eb_initialize_book(EB_Book *book);
EB_Error_Code eb_bind(EB_Book *book, const char *path);
void eb_finalize_book(EB_Book *book);
int eb_is_bound(EB_Book *book);
EB_Error_Code eb_path(EB_Book *book, char *path);
EB_Error_Code eb_disc_type(EB_Book *book, EB_Disc_Code *disc_code);
EB_Error_Code eb_character_code(EB_Book *book,
EB_Character_Code *character_code);
/* copyright.h */
int eb_have_copyright(EB_Book *book);
EB_Error_Code eb_copyright(EB_Book *book, EB_Position *position);
EB_Error_Code eb_search_cross(EB_Book *book,
const char * const input_words[]);
/* cross.c */
int eb_have_cross_search(EB_Book *book);
/* eb.c */
EB_Error_Code eb_initialize_library(void);
void eb_finalize_library(void);
/* endword.c */
int eb_have_endword_search(EB_Book *book);
EB_Error_Code eb_search_endword(EB_Book *book, const char *input_word);
/* exactword.c */
int eb_have_exactword_search(EB_Book *book);
EB_Error_Code eb_search_exactword(EB_Book *book, const char *input_word);
/* graphic.c */
int eb_have_graphic_search(EB_Book *book);
/* keyword.c */
int eb_have_keyword_search(EB_Book *book);
EB_Error_Code eb_search_keyword(EB_Book *book,
const char * const input_words[]);
/* lock.c */
int eb_pthread_enabled(void);
/* log.c */
void eb_set_log_function(void (*function)(const char *message, va_list ap));
void eb_enable_log(void);
void eb_disable_log(void);
void eb_log(const char *message, ...);
void eb_log_stderr(const char *message, va_list ap);
/* menu.c */
int eb_have_menu(EB_Book *book);
EB_Error_Code eb_menu(EB_Book *book, EB_Position *position);
int eb_have_image_menu(EB_Book *book);
EB_Error_Code eb_image_menu(EB_Book *book, EB_Position *position);
/* multi.c */
int eb_have_multi_search(EB_Book *book);
EB_Error_Code eb_multi_title(EB_Book *book, EB_Multi_Search_Code multi_id,
char *title);
EB_Error_Code eb_multi_search_list(EB_Book *book,
EB_Multi_Search_Code *search_list, int *search_count);
EB_Error_Code eb_multi_entry_count(EB_Book *book,
EB_Multi_Search_Code multi_id, int *entry_count);
EB_Error_Code eb_multi_entry_list(EB_Book *book,
EB_Multi_Search_Code multi_id, int *entry_list, int *entry_count);
EB_Error_Code eb_multi_entry_label(EB_Book *book,
EB_Multi_Search_Code multi_id, int entry_index, char *label);
int eb_multi_entry_have_candidates(EB_Book *book,
EB_Multi_Search_Code multi_id, int entry_index);
EB_Error_Code eb_multi_entry_candidates(EB_Book *book,
EB_Multi_Search_Code multi_id, int entry_index, EB_Position *position);
EB_Error_Code eb_search_multi(EB_Book *book, EB_Multi_Search_Code multi_id,
const char * const input_words[]);
/* text.c */
int eb_have_text(EB_Book *book);
EB_Error_Code eb_text(EB_Book *book, EB_Position *position);
/* search.c */
EB_Error_Code eb_hit_list(EB_Book *book, int max_hit_count, EB_Hit *hit_list,
int *hit_count);
/* subbook.c */
EB_Error_Code eb_load_all_subbooks(EB_Book *book);
EB_Error_Code eb_subbook_list(EB_Book *book, EB_Subbook_Code *subbook_list,
int *subbook_count);
EB_Error_Code eb_subbook(EB_Book *book, EB_Subbook_Code *subbook_code);
EB_Error_Code eb_subbook_title(EB_Book *book, char *title);
EB_Error_Code eb_subbook_title2(EB_Book *book, EB_Subbook_Code subbook_code,
char *title);
EB_Error_Code eb_subbook_directory(EB_Book *book, char *directory);
EB_Error_Code eb_subbook_directory2(EB_Book *book,
EB_Subbook_Code subbook_code, char *directory);
EB_Error_Code eb_set_subbook(EB_Book *book, EB_Subbook_Code subbook_code);
void eb_unset_subbook(EB_Book *book);
/* word.c */
int eb_have_word_search(EB_Book *book);
EB_Error_Code eb_search_word(EB_Book *book, const char *input_word);
/* all.c */
int eb_have_all_search(EB_Book *book);
EB_Error_Code eb_search_all_alphabet(EB_Book* book);
EB_Error_Code eb_search_all_kana(EB_Book* book);
EB_Error_Code eb_search_all_asis(EB_Book* book);
/* for backward compatibility */
#define eb_suspend eb_unset_subbook
#define eb_initialize_all_subbooks eb_load_all_subbooks
#ifdef __cplusplus
}
#endif
#endif /* not EB_EB_H */

189
endword.c Normal file
View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' supports `ENDWORD SEARCH'
* or not.
*/
int
eb_have_endword_search(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_endword_search(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* Check for the index page of endword search.
*/
if (book->subbook_current->endword_alphabet.start_page == 0
&& book->subbook_current->endword_asis.start_page == 0
&& book->subbook_current->endword_kana.start_page == 0)
goto failed;
LOG(("out: eb_have_endword_search() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_endword_search() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Endword search.
*/
EB_Error_Code
eb_search_endword(EB_Book *book, const char *input_word)
{
EB_Error_Code error_code;
EB_Word_Code word_code;
EB_Search_Context *context;
eb_lock(&book->lock);
LOG(("in: eb_search_endword(book=%d, input_word=%s)", (int)book->code,
eb_quoted_string(input_word)));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Initialize search context.
*/
eb_reset_search_contexts(book);
context = book->search_contexts;
context->code = EB_SEARCH_ENDWORD;
/*
* Make a fixed word and a canonicalized word to search from
* `input_word'.
*/
error_code = eb_set_endword(book, input_word, context->word,
context->canonicalized_word, &word_code);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Get a page number.
*/
switch (word_code) {
case EB_WORD_ALPHABET:
if (book->subbook_current->endword_alphabet.start_page != 0)
context->page = book->subbook_current->endword_alphabet.start_page;
else if (book->subbook_current->endword_asis.start_page != 0)
context->page = book->subbook_current->endword_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
case EB_WORD_KANA:
if (book->subbook_current->endword_kana.start_page != 0)
context->page = book->subbook_current->endword_kana.start_page;
else if (book->subbook_current->endword_asis.start_page != 0)
context->page = book->subbook_current->endword_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
case EB_WORD_OTHER:
if (book->subbook_current->endword_asis.start_page != 0)
context->page = book->subbook_current->endword_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
default:
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Choose comparison functions.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word;
} else if (context->page == book->subbook_current->word_kana.start_page) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word_kana_single;
context->compare_group = eb_match_word_kana_group;
} else {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word_kana_group;
}
/*
* Pre-search.
*/
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_search_endword() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_reset_search_contexts(book);
LOG(("out: eb_search_endword() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

277
error.c Normal file
View File

@ -0,0 +1,277 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Error code strings.
*/
static const char * const error_strings[] = {
/* 0 -- 4 */
"EB_SUCCESS",
"EB_ERR_MEMORY_EXHAUSTED",
"EB_ERR_EMPTY_FILE_NAME",
"EB_ERR_TOO_LONG_FILE_NAME",
"EB_ERR_BAD_FILE_NAME",
/* 5 -- 9 */
"EB_ERR_BAD_DIR_NAME",
"EB_ERR_TOO_LONG_WORD",
"EB_ERR_BAD_WORD",
"EB_ERR_EMPTY_WORD",
"EB_ERR_FAIL_GETCWD",
/* 10 -- 14 */
"EB_ERR_FAIL_OPEN_CAT",
"EB_ERR_FAIL_OPEN_CATAPP",
"EB_ERR_FAIL_OPEN_TEXT",
"EB_ERR_FAIL_OPEN_FONT",
"EB_ERR_FAIL_OPEN_APP",
/* 15 -- 19 */
"EB_ERR_FAIL_OPEN_BINARY",
"EB_ERR_FAIL_READ_CAT",
"EB_ERR_FAIL_READ_CATAPP",
"EB_ERR_FAIL_READ_TEXT",
"EB_ERR_FAIL_READ_FONT",
/* 20 -- 24 */
"EB_ERR_FAIL_READ_APP",
"EB_ERR_FAIL_READ_BINARY",
"EB_ERR_FAIL_SEEK_CAT",
"EB_ERR_FAIL_SEEK_CATAPP",
"EB_ERR_FAIL_SEEK_TEXT",
/* 25 -- 29 */
"EB_ERR_FAIL_SEEK_FONT",
"EB_ERR_FAIL_SEEK_APP",
"EB_ERR_FAIL_SEEK_BINARY",
"EB_ERR_UNEXP_CAT",
"EB_ERR_UNEXP_CATAPP",
/* 30 -- 34 */
"EB_ERR_UNEXP_TEXT",
"EB_ERR_UNEXP_FONT",
"EB_ERR_UNEXP_APP",
"EB_ERR_UNEXP_BINARY",
"EB_ERR_UNBOUND_BOOK",
/* 35 -- 39 */
"EB_ERR_UNBOUND_APP",
"EB_ERR_NO_SUB",
"EB_ERR_NO_APPSUB",
"EB_ERR_NO_FONT",
"EB_ERR_NO_TEXT",
/* 40 -- 44 */
"EB_ERR_NO_STOPCODE",
"EB_ERR_NO_ALT",
"EB_ERR_NO_CUR_SUB",
"EB_ERR_NO_CUR_APPSUB",
"EB_ERR_NO_CUR_FONT",
/* 45 -- 49 */
"EB_ERR_NO_CUR_BINARY",
"EB_ERR_NO_SUCH_SUB",
"EB_ERR_NO_SUCH_APPSUB",
"EB_ERR_NO_SUCH_FONT",
"EB_ERR_NO_SUCH_CHAR_BMP",
/* 50 -- 54 */
"EB_ERR_NO_SUCH_CHAR_TEXT",
"EB_ERR_NO_SUCH_SEARCH",
"EB_ERR_NO_SUCH_HOOK",
"EB_ERR_NO_SUCH_BINARY",
"EB_ERR_DIFF_CONTENT",
/* 55 -- 59 */
"EB_ERR_NO_PREV_SEARCH",
"EB_ERR_NO_SUCH_MULTI_ID",
"EB_ERR_NO_SUCH_ENTRY_ID",
"EB_ERR_TOO_MANY_WORDS",
"EB_ERR_NO_WORD",
/* 60 -- 64 */
"EB_ERR_NO_CANDIDATES",
"EB_ERR_END_OF_CONTENT",
"EB_ERR_NO_PREV_SEEK",
"EB_ERR_EBNET_UNSUPPORTED",
"EB_ERR_EBNET_FAIL_CONNECT",
/* 65 -- 69 */
"EB_ERR_EBNET_SERVER_BUSY",
"EB_ERR_EBNET_NO_PERMISSION",
"EB_ERR_UNBOUND_BOOKLIST",
"EB_ERR_NO_SUCH_BOOK",
NULL
};
/*
* Look up the error message corresponding to the error code `error_code'.
*/
const char *
eb_error_string(EB_Error_Code error_code)
{
const char *string;
if (0 <= error_code && error_code < EB_NUMBER_OF_ERRORS)
string = error_strings[error_code];
else
string = "EB_ERR_UNKNOWN";
return string;
}
/*
* Error messages.
*/
static const char * const error_messages[] = {
/* 0 -- 4 */
N_("no error"),
N_("memory exhausted"),
N_("an empty file name"),
N_("too long file name"),
N_("bad file name"),
/* 5 -- 9 */
N_("bad directory name"),
N_("too long word"),
N_("a word contains bad character"),
N_("an empty word"),
N_("failed to get the current working directory"),
/* 10 -- 14 */
N_("failed to open a catalog file"),
N_("failed to open an appendix catalog file"),
N_("failed to open a text file"),
N_("failed to open a font file"),
N_("failed to open an appendix file"),
/* 15 -- 19 */
N_("failed to open a binary file"),
N_("failed to read a catalog file"),
N_("failed to read an appendix catalog file"),
N_("failed to read a text file"),
N_("failed to read a font file"),
/* 20 -- 24 */
N_("failed to read an appendix file"),
N_("failed to read a binary file"),
N_("failed to seek a catalog file"),
N_("failed to seek an appendix catalog file"),
N_("failed to seek a text file"),
/* 25 -- 29 */
N_("failed to seek a font file"),
N_("failed to seek an appendix file"),
N_("failed to seek a binary file"),
N_("unexpected format in a catalog file"),
N_("unexpected format in an appendix catalog file"),
/* 30 -- 34 */
N_("unexpected format in a text file"),
N_("unexpected format in a font file"),
N_("unexpected format in an appendix file"),
N_("unexpected format in a binary file"),
N_("book not bound"),
/* 35 -- 39 */
N_("appendix not bound"),
N_("no subbook"),
N_("no subbook in the appendix"),
N_("no font"),
N_("no text file"),
/* 40 -- 44 */
N_("no stop-code"),
N_("no alternation string"),
N_("no current subbook"),
N_("no current appendix subbook"),
N_("no current font"),
/* 45 -- 49 */
N_("no current binary"),
N_("no such subbook"),
N_("no such appendix subbook"),
N_("no such font"),
N_("no such character bitmap"),
/* 50 -- 54 */
N_("no such character text"),
N_("no such search method"),
N_("no such hook"),
N_("no such binary"),
N_("different content type"),
/* 55 -- 59 */
N_("no previous search"),
N_("no such multi search"),
N_("no such multi search entry"),
N_("too many words specified"),
N_("no word specified"),
/* 60 -- 64 */
N_("no candidates"),
N_("end of content"),
N_("no previous seek"),
N_("ebnet is not supported"),
N_("failed to connect to an ebnet server"),
/* 65 -- 69 */
N_("ebnet server is busy"),
N_("no access permission"),
N_("booklist not bound"),
N_("no such book"),
NULL
};
/*
* Look up the error message corresponding to the error code `error_code'.
*/
const char *
eb_error_message(EB_Error_Code error_code)
{
const char *message;
if (0 <= error_code && error_code < EB_NUMBER_OF_ERRORS)
message = error_messages[error_code];
else
message = N_("unknown error");
#ifdef ENABLE_NLS
message = dgettext(EB_TEXT_DOMAIN_NAME, message);
#endif /* ENABLE_NLS */
return message;
}

142
error.h Normal file
View File

@ -0,0 +1,142 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_ERROR_H
#define EB_ERROR_H
#ifdef __cplusplus
extern "C" {
#endif
#include "defs.h"
/*
* Error codes.
*/
#define EB_SUCCESS 0
#define EB_ERR_MEMORY_EXHAUSTED 1
#define EB_ERR_EMPTY_FILE_NAME 2
#define EB_ERR_TOO_LONG_FILE_NAME 3
#define EB_ERR_BAD_FILE_NAME 4
#define EB_ERR_BAD_DIR_NAME 5
#define EB_ERR_TOO_LONG_WORD 6
#define EB_ERR_BAD_WORD 7
#define EB_ERR_EMPTY_WORD 8
#define EB_ERR_FAIL_GETCWD 9
#define EB_ERR_FAIL_OPEN_CAT 10
#define EB_ERR_FAIL_OPEN_CATAPP 11
#define EB_ERR_FAIL_OPEN_TEXT 12
#define EB_ERR_FAIL_OPEN_FONT 13
#define EB_ERR_FAIL_OPEN_APP 14
#define EB_ERR_FAIL_OPEN_BINARY 15
#define EB_ERR_FAIL_READ_CAT 16
#define EB_ERR_FAIL_READ_CATAPP 17
#define EB_ERR_FAIL_READ_TEXT 18
#define EB_ERR_FAIL_READ_FONT 19
#define EB_ERR_FAIL_READ_APP 20
#define EB_ERR_FAIL_READ_BINARY 21
#define EB_ERR_FAIL_SEEK_CAT 22
#define EB_ERR_FAIL_SEEK_CATAPP 23
#define EB_ERR_FAIL_SEEK_TEXT 24
#define EB_ERR_FAIL_SEEK_FONT 25
#define EB_ERR_FAIL_SEEK_APP 26
#define EB_ERR_FAIL_SEEK_BINARY 27
#define EB_ERR_UNEXP_CAT 28
#define EB_ERR_UNEXP_CATAPP 29
#define EB_ERR_UNEXP_TEXT 30
#define EB_ERR_UNEXP_FONT 31
#define EB_ERR_UNEXP_APP 32
#define EB_ERR_UNEXP_BINARY 33
#define EB_ERR_UNBOUND_BOOK 34
#define EB_ERR_UNBOUND_APP 35
#define EB_ERR_NO_SUB 36
#define EB_ERR_NO_APPSUB 37
#define EB_ERR_NO_FONT 38
#define EB_ERR_NO_TEXT 39
#define EB_ERR_NO_STOPCODE 40
#define EB_ERR_NO_ALT 41
#define EB_ERR_NO_CUR_SUB 42
#define EB_ERR_NO_CUR_APPSUB 43
#define EB_ERR_NO_CUR_FONT 44
#define EB_ERR_NO_CUR_BINARY 45
#define EB_ERR_NO_SUCH_SUB 46
#define EB_ERR_NO_SUCH_APPSUB 47
#define EB_ERR_NO_SUCH_FONT 48
#define EB_ERR_NO_SUCH_CHAR_BMP 49
#define EB_ERR_NO_SUCH_CHAR_TEXT 50
#define EB_ERR_NO_SUCH_SEARCH 51
#define EB_ERR_NO_SUCH_HOOK 52
#define EB_ERR_NO_SUCH_BINARY 53
#define EB_ERR_DIFF_CONTENT 54
#define EB_ERR_NO_PREV_SEARCH 55
#define EB_ERR_NO_SUCH_MULTI_ID 56
#define EB_ERR_NO_SUCH_ENTRY_ID 57
#define EB_ERR_TOO_MANY_WORDS 58
#define EB_ERR_NO_WORD 59
#define EB_ERR_NO_CANDIDATES 60
#define EB_ERR_END_OF_CONTENT 61
#define EB_ERR_NO_PREV_SEEK 62
#define EB_ERR_UNBOUND_BOOKLIST 67
#define EB_ERR_NO_SUCH_BOOK 68
/*
* The number of error codes.
*/
#define EB_NUMBER_OF_ERRORS 69
/*
* The maximum length of an error message.
*/
#define EB_MAX_ERROR_MESSAGE_LENGTH 127
/*
* Function declarations.
*/
/* error.c */
const char *eb_error_string(EB_Error_Code error_code);
const char *eb_error_message(EB_Error_Code error_code);
#ifdef __cplusplus
}
#endif
#endif /* not EB_ERROR_H */

188
exactword.c Normal file
View File

@ -0,0 +1,188 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' supports `EXACTWORD SEARCH'
* or not.
*/
int
eb_have_exactword_search(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_exactword_search(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* Check for the index page of word search.
*/
if (book->subbook_current->word_alphabet.start_page == 0
&& book->subbook_current->word_asis.start_page == 0
&& book->subbook_current->word_kana.start_page == 0)
goto failed;
LOG(("out: eb_have_exactword_search() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_exactword_search() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Exactword search.
*/
EB_Error_Code
eb_search_exactword(EB_Book *book, const char *input_word)
{
EB_Error_Code error_code;
EB_Word_Code word_code;
EB_Search_Context *context;
eb_lock(&book->lock);
LOG(("in: eb_search_exactword(book=%d, input_word=%s)", (int)book->code,
eb_quoted_string(input_word)));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Initialize search context.
*/
eb_reset_search_contexts(book);
context = book->search_contexts;
context->code = EB_SEARCH_EXACTWORD;
/*
* Make a fixed word and a canonicalized word to search from
* `input_word'.
*/
error_code = eb_set_word(book, input_word, context->word,
context->canonicalized_word, &word_code);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Get a page number.
*/
switch (word_code) {
case EB_WORD_ALPHABET:
if (book->subbook_current->word_alphabet.start_page != 0)
context->page = book->subbook_current->word_alphabet.start_page;
else if (book->subbook_current->word_asis.start_page != 0)
context->page = book->subbook_current->word_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
case EB_WORD_KANA:
if (book->subbook_current->word_kana.start_page != 0)
context->page = book->subbook_current->word_kana.start_page;
else if (book->subbook_current->word_asis.start_page != 0)
context->page = book->subbook_current->word_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
case EB_WORD_OTHER:
if (book->subbook_current->word_asis.start_page != 0)
context->page = book->subbook_current->word_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
default:
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Choose comparison functions.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_exact_pre_match_word_latin;
context->compare_single = eb_exact_match_word_latin;
context->compare_group = eb_exact_match_word_latin;
} else if (context->page == book->subbook_current->word_kana.start_page) {
context->compare_pre = eb_exact_pre_match_word_jis;
context->compare_single = eb_exact_match_word_kana_single;
context->compare_group = eb_exact_match_word_kana_group;
} else {
context->compare_pre = eb_exact_pre_match_word_jis;
context->compare_single = eb_exact_match_word_jis;
context->compare_group = eb_exact_match_word_kana_group;
}
/*
* Pre-search.
*/
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_search_exactword() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_reset_search_contexts(book);
LOG(("out: eb_search_exactword() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

609
filename.c Normal file
View File

@ -0,0 +1,609 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Canonicalize `path_name' (UNIX version).
* Convert a path name to an absolute path.
*/
EB_Error_Code
eb_canonicalize_path_name(char *path_name)
{
char cwd[EB_MAX_PATH_LENGTH + 1];
char temporary_path_name[EB_MAX_PATH_LENGTH + 1];
char *last_slash;
if (*path_name != '/') {
/*
* `path_name' is an relative path. Convert to an absolute
* path.
*/
if (getcwd(cwd, EB_MAX_PATH_LENGTH + 1) == NULL)
return EB_ERR_FAIL_GETCWD;
if (EB_MAX_PATH_LENGTH < strlen(cwd) + 1 + strlen(path_name))
return EB_ERR_TOO_LONG_FILE_NAME;
if (strcmp(path_name, ".") == 0) {
strcpy(path_name, cwd);
} else if (strncmp(path_name, "./", 2) == 0) {
sprintf(temporary_path_name, "%s/%s", cwd, path_name + 2);
strcpy(path_name, temporary_path_name);
} else {
sprintf(temporary_path_name, "%s/%s", cwd, path_name);
strcpy(path_name, temporary_path_name);
}
}
/*
* Unless `path_name' is "/", eliminate `/' in the tail of the
* path name.
*/
last_slash = strrchr(path_name, '/');
if (last_slash != path_name && *(last_slash + 1) == '\0')
*last_slash = '\0';
return EB_SUCCESS;
}
/*
* Canonicalize file name.
* - Suffix including dot is removed
* - Version including semicolon is removed.
* - Letters are converted to upper case.
*
* We minght fail to load a file after we fix the file name.
* If loading the file is tried again, we need the original file name,
* not fixed file name. Therefore, we get orignal file name from fixed
* file name using this function.
*/
void
eb_canonicalize_file_name(char *file_name)
{
char *p;
for (p = file_name; *p != '\0' && *p != '.' && *p != ';'; p++)
*p = ASCII_TOUPPER(*p);
*p = '\0';
}
/*
* Rewrite `directory_name' to a real directory name in the `path' directory.
*
* If a directory matched to `directory_name' exists, then EB_SUCCESS is
* returned, and `directory_name' is rewritten to that name. Otherwise
* EB_ERR_BAD_DIR_NAME is returned.
*/
EB_Error_Code
eb_fix_directory_name(const char *path, char *directory_name)
{
struct dirent *entry;
DIR *dir;
/*
* Open the directory `path'.
*/
dir = opendir(path);
if (dir == NULL)
goto failed;
for (;;) {
/*
* Read the directory entry.
*/
entry = readdir(dir);
if (entry == NULL)
goto failed;
if (strcasecmp(entry->d_name, directory_name) == 0)
break;
}
strcpy(directory_name, entry->d_name);
closedir(dir);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
if (dir != NULL)
closedir(dir);
return EB_ERR_BAD_DIR_NAME;
}
/*
* Rewrite `sub_directory_name' to a real sub directory name in the
* `path/directory_name' directory.
*
* If a directory matched to `sub_directory_name' exists, then EB_SUCCESS
* is returned, and `directory_name' is rewritten to that name. Otherwise
* EB_ERR_BAD_FILE_NAME is returned.
*/
EB_Error_Code
eb_fix_directory_name2(const char *path, const char *directory_name,
char *sub_directory_name)
{
char sub_path_name[EB_MAX_PATH_LENGTH + 1];
eb_compose_path_name(path, directory_name, sub_path_name);
return eb_fix_directory_name(sub_path_name, sub_directory_name);
}
/*
* Fix suffix of `path_name'.
*
* If `suffix' is an empty string, delete suffix from `path_name'.
* Otherwise, add `suffix' to `path_name'.
*/
void
eb_fix_path_name_suffix(char *path_name, const char *suffix)
{
char *base_name;
char *dot;
char *semicolon;
base_name = strrchr(path_name, '/');
if (base_name == NULL)
base_name = path_name;
else
base_name++;
dot = strchr(base_name, '.');
semicolon = strchr(base_name, ';');
if (*suffix == '\0') {
/*
* Remove `.xxx' from `fixed_file_name':
* foo.xxx --> foo
* foo.xxx;1 --> foo;1
* foo. --> foo. (unchanged)
* foo.;1 --> foo.;1 (unchanged)
*/
if (dot != NULL && *(dot + 1) != '\0' && *(dot + 1) != ';') {
if (semicolon != NULL)
sprintf(dot, ";%c", *(semicolon + 1));
else
*dot = '\0';
}
} else {
/*
* Add `.xxx' to `fixed_file_name':
* foo --> foo.xxx
* foo. --> foo.xxx
* foo;1 --> foo.xxx;1
* foo.;1 --> foo.xxx;1
* foo.xxx --> foo.xxx (unchanged)
*/
if (dot != NULL) {
if (semicolon != NULL)
sprintf(dot, "%s;%c", suffix, *(semicolon + 1));
else
strcpy(dot, suffix);
} else {
if (semicolon != NULL)
sprintf(semicolon, "%s;%c", suffix, *(semicolon + 1));
else
strcat(base_name, suffix);
}
}
}
#define FOUND_NONE 0
#define FOUND_EBZ 1
#define FOUND_BASENAME 2
#define FOUND_ORG 3
/*
* Rewrite `found_file_name' to a real file name in the `path_name'
* directory.
*
* If a file matched to `target_file_name' exists, then EB_SUCCESS
* is returned, and `found_file_name' is rewritten to that name.
* Otherwise EB_ERR_BAD_FILE_NAME is returned.
*
* Note that `target_file_name' must not contain `.' or excceed
* EB_MAX_DIRECTORY_NAME_LENGTH characters.
*/
EB_Error_Code
eb_find_file_name(const char *path_name, const char *target_file_name,
char *found_file_name)
{
char ebz_target_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
char org_target_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
char candidate_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
DIR *dir;
struct dirent *entry;
size_t d_namlen;
int found = FOUND_NONE;
strcpy(ebz_target_file_name, target_file_name);
strcat(ebz_target_file_name, ".ebz");
strcpy(org_target_file_name, target_file_name);
strcat(org_target_file_name, ".org");
candidate_file_name[0] = '\0';
/*
* Open the directory `path_name'.
*/
dir = opendir(path_name);
if (dir == NULL)
goto failed;
for (;;) {
/*
* Read the directory entry.
*/
entry = readdir(dir);
if (entry == NULL)
break;
/*
* Compare the given file names and the current entry name.
* We consider they are matched when one of the followings
* is true:
*
* <target name> == <entry name>
* <target name>+";1' == <entry name>
* <target name>+"." == <entry name>
* <target name>+".;1" == <entry name>
* <target name>+".ebz" == <entry name>
* <target name>+".ebz;1" == <entry name>
* <target name>+".org" == <entry name>
* <target name>+".org;1" == <entry name>
*
* All the comparisons are done without case sensitivity.
* We support version number ";1" only.
*/
d_namlen = strlen(entry->d_name);
if (2 < d_namlen
&& *(entry->d_name + d_namlen - 2) == ';'
&& ASCII_ISDIGIT(*(entry->d_name + d_namlen - 1))) {
d_namlen -= 2;
}
if (1 < d_namlen && *(entry->d_name + d_namlen - 1) == '.')
d_namlen--;
if (strcasecmp(entry->d_name, ebz_target_file_name) == 0
&& *(ebz_target_file_name + d_namlen) == '\0'
&& found < FOUND_EBZ) {
strcpy(candidate_file_name, entry->d_name);
found = FOUND_EBZ;
}
if (strncasecmp(entry->d_name, target_file_name, d_namlen) == 0
&& *(target_file_name + d_namlen) == '\0'
&& found < FOUND_BASENAME) {
strcpy(candidate_file_name, entry->d_name);
found = FOUND_BASENAME;
}
if (strcasecmp(entry->d_name, org_target_file_name) == 0
&& *(org_target_file_name + d_namlen) == '\0'
&& found < FOUND_ORG) {
strcpy(candidate_file_name, entry->d_name);
found = FOUND_ORG;
break;
}
}
if (found == FOUND_NONE)
goto failed;
closedir(dir);
strcpy(found_file_name, candidate_file_name);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
if (dir != NULL)
closedir(dir);
return EB_ERR_BAD_FILE_NAME;
}
/*
* Rewrite `file_name' to a real file name in the directory
* `path_name/sub_directory_name'.
*
* If a file matched to `file_name' exists, then EB_SUCCESS is returned,
* and `file_name' is rewritten to that name. Otherwise EB_ERR_BAD_FILE_NAME
* is returned.
*/
EB_Error_Code
eb_find_file_name2(const char *path_name, const char *sub_directory_name,
const char *target_file_name, char *found_file_name)
{
char sub_path_name[EB_MAX_PATH_LENGTH + 1];
eb_compose_path_name(path_name, sub_directory_name, sub_path_name);
return eb_find_file_name(sub_path_name, target_file_name, found_file_name);
}
EB_Error_Code
eb_find_file_name3(const char *path_name, const char *sub_directory_name,
const char *sub2_directory_name, const char *target_file_name,
char *found_file_name)
{
char sub2_path_name[EB_MAX_PATH_LENGTH + 1];
eb_compose_path_name2(path_name, sub_directory_name, sub2_directory_name,
sub2_path_name);
return eb_find_file_name(sub2_path_name, target_file_name,
found_file_name);
}
/*
* Compose a file name
* `path_name/file_name'
* and copy it into `composed_path_name'.
*/
void
eb_compose_path_name(const char *path_name, const char *file_name,
char *composed_path_name)
{
if (strcmp(path_name, "/") == 0)
sprintf(composed_path_name, "%s%s", path_name, file_name);
else
sprintf(composed_path_name, "%s/%s", path_name, file_name);
}
/*
* Compose a file name
* `path_name/sub_directory/file_name'
* and copy it into `composed_path_name'.
*/
void
eb_compose_path_name2(const char *path_name, const char *sub_directory_name,
const char *file_name, char *composed_path_name)
{
if (strcmp(path_name, "/") == 0) {
sprintf(composed_path_name, "%s%s/%s",
path_name, sub_directory_name, file_name);
} else {
sprintf(composed_path_name, "%s/%s/%s",
path_name, sub_directory_name, file_name);
}
}
/*
* Compose a file name
* `path_name/sub_directory/sub2_directory/file_name'
* and copy it into `composed_path_name'.
*/
void
eb_compose_path_name3(const char *path_name, const char *sub_directory_name,
const char *sub2_directory_name, const char *file_name,
char *composed_path_name)
{
if (strcmp(path_name, "/") == 0) {
sprintf(composed_path_name, "%s%s/%s/%s",
path_name, sub_directory_name, sub2_directory_name, file_name);
} else {
sprintf(composed_path_name, "%s/%s/%s/%s",
path_name, sub_directory_name, sub2_directory_name, file_name);
}
}
/*
* Compose movie file name from argv[], and copy the result to
* `composed_file_name'. Note that upper letters are converted to lower
* letters.
*
* If a file `composed_path_name' exists, then EB_SUCCESS is returned.
* Otherwise EB_ERR_BAD_FILE_NAME is returned.
*/
EB_Error_Code
eb_compose_movie_file_name(const unsigned int *argv, char *composed_file_name)
{
unsigned short jis_characters[EB_MAX_DIRECTORY_NAME_LENGTH];
const unsigned int *arg_p;
char *composed_p;
unsigned short c;
int i;
/*
* Initialize `jis_characters[]'.
*/
for (i = 0, arg_p = argv;
i + 1 < EB_MAX_DIRECTORY_NAME_LENGTH; i += 2, arg_p++) {
jis_characters[i] = (*arg_p >> 16) & 0xffff;
jis_characters[i + 1] = (*arg_p) & 0xffff;
}
if (i < EB_MAX_DIRECTORY_NAME_LENGTH)
jis_characters[i] = (*arg_p >> 16) & 0xffff;
/*
* Compose file name.
*/
for (i = 0, composed_p = composed_file_name;
i < EB_MAX_DIRECTORY_NAME_LENGTH; i++, composed_p++) {
c = jis_characters[i];
if (c == 0x2121 || c == 0x0000)
break;
if ((0x2330 <= c && c <= 0x2339) || (0x2361 <= c && c <= 0x237a))
*composed_p = c & 0xff;
else if (0x2341 <= c && c <= 0x235a)
*composed_p = (c | 0x20) & 0xff;
else
return EB_ERR_BAD_FILE_NAME;
}
*composed_p = '\0';
return EB_SUCCESS;
}
/*
* This function is similar to eb_compose_movie_file_name(), but it
* returns full path of the movie file name.
*/
EB_Error_Code
eb_compose_movie_path_name(EB_Book *book, const unsigned int *argv,
char *composed_path_name)
{
EB_Subbook *subbook;
EB_Error_Code error_code;
char composed_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
/*
* Lock the book.
*/
eb_lock(&book->lock);
LOG(("in: eb_compose_movie_path_name(book=%d, argv=%x)",
(int)book->code, argv));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
subbook = book->subbook_current;
error_code = eb_compose_movie_file_name(argv, composed_file_name);
if (error_code != EB_SUCCESS)
goto failed;
error_code = eb_find_file_name3(book->path, subbook->directory_name,
subbook->movie_directory_name, composed_file_name, composed_file_name);
if (error_code != EB_SUCCESS)
goto failed;
eb_compose_path_name3(book->path, subbook->directory_name,
subbook->movie_directory_name, composed_file_name, composed_path_name);
LOG(("out: eb_compse_movie_path_name() = %s",
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_compse_movie_path_name() = %s",
eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Decompose movie file name into argv[]. This is the reverse of
* eb_compose_movie_file_name(). Note that lower letters are converted
* to upper letters.
*
* EB_SUCCESS is returned upon success, EB_ERR_BAD_FILE_NAME otherwise.
*/
EB_Error_Code
eb_decompose_movie_file_name(unsigned int *argv,
const char *composed_file_name)
{
unsigned short jis_characters[EB_MAX_DIRECTORY_NAME_LENGTH];
unsigned int *arg_p;
const char *composed_p;
int i;
/*
* Initialize `jis_characters[]'.
*/
for (i = 0; i < EB_MAX_DIRECTORY_NAME_LENGTH; i++)
jis_characters[i] = 0x0000;
/*
* Set jis_characters[].
*/
for (i = 0, composed_p = composed_file_name;
i < EB_MAX_DIRECTORY_NAME_LENGTH && *composed_p != '\0';
i++, composed_p++) {
if ('0' <= *composed_p && *composed_p <= '9')
jis_characters[i] = 0x2330 + (*composed_p - '0');
else if ('A' <= *composed_p && *composed_p <= 'Z')
jis_characters[i] = 0x2341 + (*composed_p - 'A');
else if ('a' <= *composed_p && *composed_p <= 'z')
jis_characters[i] = 0x2341 + (*composed_p - 'a');
else
return EB_ERR_BAD_FILE_NAME;
}
if (*composed_p != '\0')
return EB_ERR_BAD_FILE_NAME;
/*
* Decompose file name.
*/
for (i = 0, arg_p = argv;
i + 1 < EB_MAX_DIRECTORY_NAME_LENGTH; i += 2, arg_p++) {
*arg_p = (jis_characters[i] << 16) | jis_characters[i + 1];
}
if (i < EB_MAX_DIRECTORY_NAME_LENGTH) {
*arg_p++ = jis_characters[i] << 16;
}
*arg_p = '\0';
return EB_SUCCESS;
}
void
eb_path_name_zio_code(const char *path_name, Zio_Code default_zio_code,
Zio_Code *zio_code)
{
const char *base_name;
const char *dot;
base_name = strrchr(path_name, '/');
if (base_name != NULL)
base_name++;
else
base_name = path_name;
dot = strchr(base_name, '.');
if (dot != NULL && strncasecmp(dot, ".ebz", 4) == 0)
*zio_code = ZIO_EBZIP1;
else if (dot != NULL && strncasecmp(dot, ".org", 4) == 0)
*zio_code = ZIO_PLAIN;
else
*zio_code = default_zio_code;
}

539
font.c Normal file
View File

@ -0,0 +1,539 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "font.h"
#include "build-post.h"
/*
* Initialize all fonts in the current subbook.
*/
void
eb_initialize_fonts(EB_Book *book)
{
EB_Subbook *subbook;
EB_Font *font;
int i;
LOG(("in: eb_initialize_fonts(book=%d)", (int)book->code));
subbook = book->subbook_current;
for (i = 0, font = subbook->narrow_fonts; i < EB_MAX_FONTS; i++, font++) {
font->font_code = EB_FONT_INVALID;
font->initialized = 0;
font->start = -1;
font->end = -1;
font->page = 0;
font->glyphs = NULL;
zio_initialize(&font->zio);
}
for (i = 0, font = subbook->wide_fonts; i < EB_MAX_FONTS; i++, font++) {
font->font_code = EB_FONT_INVALID;
font->initialized = 0;
font->start = -1;
font->end = -1;
font->page = 0;
font->glyphs = NULL;
zio_initialize(&font->zio);
}
LOG(("out: eb_initialize_fonts()"));
}
/*
* Load font files.
*/
void
eb_load_font_headers(EB_Book *book)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Font_Code i;
LOG(("in: eb_load_fonts(book=%d)", (int)book->code));
subbook = book->subbook_current;
/*
* Load narrow font headers.
*/
for (i = 0; i < EB_MAX_FONTS; i++) {
if (subbook->narrow_fonts[i].font_code == EB_FONT_INVALID
|| subbook->narrow_fonts[i].initialized)
continue;
error_code = eb_open_narrow_font_file(book, i);
if (error_code == EB_SUCCESS)
error_code = eb_load_narrow_font_header(book, i);
if (error_code != EB_SUCCESS)
subbook->narrow_fonts[i].font_code = EB_FONT_INVALID;
subbook->narrow_fonts[i].initialized = 1;
zio_close(&subbook->narrow_fonts[i].zio);
}
/*
* Load wide font header.
*/
for (i = 0; i < EB_MAX_FONTS; i++) {
if (subbook->wide_fonts[i].font_code == EB_FONT_INVALID
|| subbook->wide_fonts[i].initialized)
continue;
error_code = eb_open_wide_font_file(book, i);
if (error_code == EB_SUCCESS)
error_code = eb_load_wide_font_header(book, i);
if (error_code != EB_SUCCESS)
subbook->wide_fonts[i].font_code = EB_FONT_INVALID;
subbook->wide_fonts[i].initialized = 1;
zio_close(&subbook->wide_fonts[i].zio);
}
LOG(("out: eb_load_font_headers()"));
}
/*
* Finalize all fonts in the current subbook.
*/
void
eb_finalize_fonts(EB_Book *book)
{
EB_Subbook *subbook;
EB_Font *font;
int i;
LOG(("in: eb_finalize_fonts(book=%d)", (int)book->code));
subbook = book->subbook_current;
for (i = 0, font = subbook->narrow_fonts; i < EB_MAX_FONTS; i++, font++) {
zio_finalize(&font->zio);
if (font->glyphs != NULL) {
free(font->glyphs);
font->glyphs = NULL;
}
}
for (i = 0, font = subbook->wide_fonts; i < EB_MAX_FONTS; i++, font++) {
zio_finalize(&font->zio);
if (font->glyphs != NULL) {
free(font->glyphs);
font->glyphs = NULL;
}
}
LOG(("out: eb_finalize_fonts()"));
}
/*
* Look up the height of the current font of the current subbook in
* `book'.
*/
EB_Error_Code
eb_font(EB_Book *book, EB_Font_Code *font_code)
{
EB_Error_Code error_code;
eb_lock(&book->lock);
LOG(("in: eb_font(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Look up the height of the current font.
*/
if (book->subbook_current->narrow_current != NULL)
*font_code = book->subbook_current->narrow_current->font_code;
else if (book->subbook_current->wide_current != NULL)
*font_code = book->subbook_current->wide_current->font_code;
else {
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
}
LOG(("out: eb_font(font_code=%d) = %s", (int)*font_code,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*font_code = EB_FONT_INVALID;
LOG(("out: eb_font() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Set the font with `font_code' as the current font of the current
* subbook in `book'.
*/
EB_Error_Code
eb_set_font(EB_Book *book, EB_Font_Code font_code)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
eb_lock(&book->lock);
LOG(("in: eb_set_font(book=%d, font_code=%d)", (int)book->code,
(int)font_code));
/*
* Check `font_code'.
*/
if (font_code < 0 || EB_MAX_FONTS <= font_code) {
error_code = EB_ERR_NO_SUCH_FONT;
goto failed;
}
/*
* Current subbook must have been set.
*/
subbook = book->subbook_current;
if (subbook == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* If the current font is the font with `font_code', return immediately.
* Otherwise close the current font and continue.
*/
if (subbook->narrow_current != NULL) {
if (subbook->narrow_current->font_code == font_code)
goto succeeded;
if (book->disc_code == EB_DISC_EPWING)
zio_close(&subbook->narrow_current->zio);
subbook->narrow_current = NULL;
}
if (subbook->wide_current != NULL) {
if (subbook->wide_current->font_code == font_code)
goto succeeded;
if (book->disc_code == EB_DISC_EPWING)
zio_close(&subbook->wide_current->zio);
subbook->wide_current = NULL;
}
/*
* Set the current font.
*/
if (subbook->narrow_fonts[font_code].font_code != EB_FONT_INVALID)
subbook->narrow_current = subbook->narrow_fonts + font_code;
if (subbook->wide_fonts[font_code].font_code != EB_FONT_INVALID)
subbook->wide_current = subbook->wide_fonts + font_code;
if (subbook->narrow_current == NULL && subbook->wide_current == NULL) {
error_code = EB_ERR_NO_SUCH_FONT;
goto failed;
}
/*
* Initialize current font informtaion.
*/
if (subbook->narrow_current != NULL) {
error_code = eb_open_narrow_font_file(book, font_code);
if (error_code != EB_SUCCESS)
goto failed;
}
if (subbook->wide_current != NULL) {
error_code = eb_open_wide_font_file(book, font_code);
if (error_code != EB_SUCCESS)
goto failed;
}
succeeded:
LOG(("out: eb_set_font() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_unset_font(book);
LOG(("out: eb_set_font() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Unset the font in the current subbook in `book'.
*/
void
eb_unset_font(EB_Book *book)
{
EB_Subbook *subbook;
eb_lock(&book->lock);
LOG(("in: eb_unset_font(book=%d)", (int)book->code));
subbook = book->subbook_current;
if (subbook == NULL)
goto succeeded;
/*
* Close font files.
*/
if (subbook->narrow_current != NULL) {
zio_close(&subbook->narrow_current->zio);
if (subbook->narrow_current->glyphs != NULL) {
free(subbook->narrow_current->glyphs);
subbook->narrow_current->glyphs = NULL;
}
}
if (subbook->wide_current != NULL) {
zio_close(&subbook->wide_current->zio);
if (subbook->wide_current->glyphs != NULL) {
free(subbook->wide_current->glyphs);
subbook->wide_current->glyphs = NULL;
}
}
book->subbook_current->narrow_current = NULL;
book->subbook_current->wide_current = NULL;
succeeded:
LOG(("out: eb_unset_font()"));
eb_unlock(&book->lock);
}
/*
* Make a list of fonts in the current subbook in `book'.
*/
EB_Error_Code
eb_font_list(EB_Book *book, EB_Font_Code *font_list, int *font_count)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Font_Code *list_p;
int i;
eb_lock(&book->lock);
LOG(("in: eb_font_list(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
subbook = book->subbook_current;
if (subbook == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Scan the font table in the book.
*/
subbook = book->subbook_current;
list_p = font_list;
*font_count = 0;
for (i = 0; i < EB_MAX_FONTS; i++) {
if (subbook->narrow_fonts[i].font_code != EB_FONT_INVALID
|| subbook->wide_fonts[i].font_code != EB_FONT_INVALID) {
*list_p++ = i;
*font_count += 1;
}
}
LOG(("out: eb_font(font_count=%d) = %s", *font_count,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_font_list() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Test whether the current subbook in `book' has a font with
* `font_code' or not.
*/
int
eb_have_font(EB_Book *book, EB_Font_Code font_code)
{
EB_Subbook *subbook;
eb_lock(&book->lock);
LOG(("in: eb_have_font(book=%d, font_code=%d)", (int)book->code,
(int)font_code));
/*
* Check `font_code'.
*/
if (font_code < 0 || EB_MAX_FONTS <= font_code)
goto failed;
/*
* Current subbook must have been set.
*/
subbook = book->subbook_current;
if (subbook == NULL)
goto failed;
if (subbook->narrow_fonts[font_code].font_code == EB_FONT_INVALID
&& subbook->wide_fonts[font_code].font_code == EB_FONT_INVALID)
goto failed;
LOG(("out: eb_have_font() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_font() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Get height of the font `font_code' in the current subbook of `book'.
*/
EB_Error_Code
eb_font_height(EB_Book *book, int *height)
{
EB_Error_Code error_code;
EB_Font_Code font_code;
eb_lock(&book->lock);
LOG(("in: eb_font_height(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* The narrow font must exist in the current subbook.
*/
if (book->subbook_current->narrow_current != NULL)
font_code = book->subbook_current->narrow_current->font_code;
else if (book->subbook_current->wide_current != NULL)
font_code = book->subbook_current->wide_current->font_code;
else {
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
}
/*
* Calculate height.
*/
error_code = eb_font_height2(font_code, height);
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_font_heigt(height=%d) = %s", *height,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*height = 0;
LOG(("out: eb_font_height() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Get height of the font `font_code'.
*/
EB_Error_Code
eb_font_height2(EB_Font_Code font_code, int *height)
{
EB_Error_Code error_code;
LOG(("in: eb_font_height2(font_code=%d)", (int)font_code));
switch (font_code) {
case EB_FONT_16:
*height = EB_HEIGHT_FONT_16;
break;
case EB_FONT_24:
*height = EB_HEIGHT_FONT_24;
break;
case EB_FONT_30:
*height = EB_HEIGHT_FONT_30;
break;
case EB_FONT_48:
*height = EB_HEIGHT_FONT_48;
break;
default:
error_code = EB_ERR_NO_SUCH_FONT;
goto failed;
}
LOG(("out: eb_font_heigt2(height=%d) = %s", *height,
eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*height = 0;
LOG(("out: eb_font_height2() = %s", eb_error_string(error_code)));
return error_code;
}

196
font.h Normal file
View File

@ -0,0 +1,196 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_FONT_H
#define EB_FONT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include "defs.h"
/*
* Font types.
*/
#define EB_FONT_16 0
#define EB_FONT_24 1
#define EB_FONT_30 2
#define EB_FONT_48 3
#define EB_FONT_INVALID -1
/*
* Font sizes.
*/
#define EB_SIZE_NARROW_FONT_16 16
#define EB_SIZE_WIDE_FONT_16 32
#define EB_SIZE_NARROW_FONT_24 48
#define EB_SIZE_WIDE_FONT_24 72
#define EB_SIZE_NARROW_FONT_30 60
#define EB_SIZE_WIDE_FONT_30 120
#define EB_SIZE_NARROW_FONT_48 144
#define EB_SIZE_WIDE_FONT_48 288
/*
* Font width.
*/
#define EB_WIDTH_NARROW_FONT_16 8
#define EB_WIDTH_WIDE_FONT_16 16
#define EB_WIDTH_NARROW_FONT_24 16
#define EB_WIDTH_WIDE_FONT_24 24
#define EB_WIDTH_NARROW_FONT_30 16
#define EB_WIDTH_WIDE_FONT_30 32
#define EB_WIDTH_NARROW_FONT_48 24
#define EB_WIDTH_WIDE_FONT_48 48
/*
* Font height.
*/
#define EB_HEIGHT_FONT_16 16
#define EB_HEIGHT_FONT_24 24
#define EB_HEIGHT_FONT_30 30
#define EB_HEIGHT_FONT_48 48
/*
* Bitmap image sizes.
*/
#define EB_SIZE_NARROW_FONT_16_XBM 184
#define EB_SIZE_WIDE_FONT_16_XBM 284
#define EB_SIZE_NARROW_FONT_16_XPM 266
#define EB_SIZE_WIDE_FONT_16_XPM 395
#define EB_SIZE_NARROW_FONT_16_GIF 186
#define EB_SIZE_WIDE_FONT_16_GIF 314
#define EB_SIZE_NARROW_FONT_16_BMP 126
#define EB_SIZE_WIDE_FONT_16_BMP 126
#define EB_SIZE_NARROW_FONT_16_PNG 131
#define EB_SIZE_WIDE_FONT_16_PNG 147
#define EB_SIZE_NARROW_FONT_24_XBM 383
#define EB_SIZE_WIDE_FONT_24_XBM 533
#define EB_SIZE_NARROW_FONT_24_XPM 555
#define EB_SIZE_WIDE_FONT_24_XPM 747
#define EB_SIZE_NARROW_FONT_24_GIF 450
#define EB_SIZE_WIDE_FONT_24_GIF 642
#define EB_SIZE_NARROW_FONT_24_BMP 158
#define EB_SIZE_WIDE_FONT_24_BMP 158
#define EB_SIZE_NARROW_FONT_24_PNG 171
#define EB_SIZE_WIDE_FONT_24_PNG 195
#define EB_SIZE_NARROW_FONT_30_XBM 458
#define EB_SIZE_WIDE_FONT_30_XBM 833
#define EB_SIZE_NARROW_FONT_30_XPM 675
#define EB_SIZE_WIDE_FONT_30_XPM 1155
#define EB_SIZE_NARROW_FONT_30_GIF 552
#define EB_SIZE_WIDE_FONT_30_GIF 1032
#define EB_SIZE_NARROW_FONT_30_BMP 182
#define EB_SIZE_WIDE_FONT_30_BMP 182
#define EB_SIZE_NARROW_FONT_30_PNG 189
#define EB_SIZE_WIDE_FONT_30_PNG 249
#define EB_SIZE_NARROW_FONT_48_XBM 983
#define EB_SIZE_WIDE_FONT_48_XBM 1883
#define EB_SIZE_NARROW_FONT_48_XPM 1419
#define EB_SIZE_WIDE_FONT_48_XPM 2571
#define EB_SIZE_NARROW_FONT_48_GIF 1242
#define EB_SIZE_WIDE_FONT_48_GIF 2394
#define EB_SIZE_NARROW_FONT_48_BMP 254
#define EB_SIZE_WIDE_FONT_48_BMP 446
#define EB_SIZE_NARROW_FONT_48_PNG 291
#define EB_SIZE_WIDE_FONT_48_PNG 435
#define EB_SIZE_FONT_IMAGE EB_SIZE_WIDE_FONT_48_XPM
/*
* Function declarations.
*/
/* bitmap.c */
EB_Error_Code eb_narrow_font_xbm_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_narrow_font_xpm_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_narrow_font_gif_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_narrow_font_bmp_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_narrow_font_png_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_wide_font_xbm_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_wide_font_xpm_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_wide_font_gif_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_wide_font_bmp_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_wide_font_png_size(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_bitmap_to_xbm(const char *bitmap, int width, int height,
char *xbm, size_t *xbm_length);
EB_Error_Code eb_bitmap_to_xpm(const char *bitmap, int width, int height,
char *xpm, size_t *xpm_length);
EB_Error_Code eb_bitmap_to_gif(const char *bitmap, int width, int height,
char *gif, size_t *gif_length);
EB_Error_Code eb_bitmap_to_bmp(const char *bitmap, int width, int height,
char *bmp, size_t *bmp_length);
EB_Error_Code eb_bitmap_to_png(const char *bitmap, int width, int height,
char *png, size_t *png_length);
/* font.c */
EB_Error_Code eb_font(EB_Book *book, EB_Font_Code *font_code);
EB_Error_Code eb_set_font(EB_Book *book, EB_Font_Code font_code);
void eb_unset_font(EB_Book *book);
EB_Error_Code eb_font_list(EB_Book *book, EB_Font_Code *font_list,
int *font_count);
int eb_have_font(EB_Book *book, EB_Font_Code font_code);
EB_Error_Code eb_font_height(EB_Book *book, int *height);
EB_Error_Code eb_font_height2(EB_Font_Code font_code, int *height);
/* narwfont.c */
int eb_have_narrow_font(EB_Book *book);
EB_Error_Code eb_narrow_font_width(EB_Book *book, int *width);
EB_Error_Code eb_narrow_font_width2(EB_Font_Code font_code, int *width);
EB_Error_Code eb_narrow_font_size(EB_Book *book, size_t *size);
EB_Error_Code eb_narrow_font_size2(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_narrow_font_start(EB_Book *book, int *start);
EB_Error_Code eb_narrow_font_end(EB_Book *book, int *end);
EB_Error_Code eb_narrow_font_character_bitmap(EB_Book *book, int, char *);
EB_Error_Code eb_forward_narrow_font_character(EB_Book *book, int, int *);
EB_Error_Code eb_backward_narrow_font_character(EB_Book *book, int, int *);
/* widefont.c */
int eb_have_wide_font(EB_Book *book);
EB_Error_Code eb_wide_font_width(EB_Book *book, int *width);
EB_Error_Code eb_wide_font_width2(EB_Font_Code font_code, int *width);
EB_Error_Code eb_wide_font_size(EB_Book *book, size_t *size);
EB_Error_Code eb_wide_font_size2(EB_Font_Code font_code, size_t *size);
EB_Error_Code eb_wide_font_start(EB_Book *book, int *start);
EB_Error_Code eb_wide_font_end(EB_Book *book, int *end);
EB_Error_Code eb_wide_font_character_bitmap(EB_Book *book,
int character_number, char *bitmap);
EB_Error_Code eb_forward_wide_font_character(EB_Book *book, int n,
int *character_number);
EB_Error_Code eb_backward_wide_font_character(EB_Book *book, int n,
int *character_number);
#ifdef __cplusplus
}
#endif
#endif /* not EB_FONT_H */

319
hook.c Normal file
View File

@ -0,0 +1,319 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "appendix.h"
#include "text.h"
#include "build-post.h"
/*
* Default hookset.
*/
EB_Hookset eb_default_hookset;
/*
* Initialize default hookset.
*/
void
eb_initialize_default_hookset(void)
{
LOG(("in: eb_initialize_default_hookset()"));
eb_initialize_hookset(&eb_default_hookset);
LOG(("out: eb_initialize_default_hookset()"));
}
/*
* Initialize a hookset.
*/
void
eb_initialize_hookset(EB_Hookset *hookset)
{
int i;
LOG(("in: eb_initialize_hookset()"));
eb_initialize_lock(&hookset->lock);
for (i = 0; i < EB_NUMBER_OF_HOOKS; i++) {
hookset->hooks[i].code = i;
hookset->hooks[i].function = NULL;
}
hookset->hooks[EB_HOOK_NARROW_JISX0208].function
= eb_hook_euc_to_ascii;
hookset->hooks[EB_HOOK_NARROW_FONT].function
= eb_hook_narrow_character_text;
hookset->hooks[EB_HOOK_WIDE_FONT].function
= eb_hook_wide_character_text;
hookset->hooks[EB_HOOK_NEWLINE].function
= eb_hook_newline;
LOG(("out: eb_initialize_hookset()"));
}
/*
* Finalize a hookset.
*/
void
eb_finalize_hookset(EB_Hookset *hookset)
{
int i;
LOG(("in: eb_finalize_hookset()"));
for (i = 0; i < EB_NUMBER_OF_HOOKS; i++) {
hookset->hooks[i].code = i;
hookset->hooks[i].function = NULL;
}
eb_finalize_lock(&hookset->lock);
LOG(("out: eb_finalize_hookset()"));
}
/*
* Set a hook.
*/
EB_Error_Code
eb_set_hook(EB_Hookset *hookset, const EB_Hook *hook)
{
EB_Error_Code error_code;
eb_lock(&hookset->lock);
LOG(("in: eb_set_hook(hook=%d)", (int)hook->code));
/*
* Set a hook.
*/
if (hook->code < 0 || EB_NUMBER_OF_HOOKS <= hook->code) {
error_code = EB_ERR_NO_SUCH_HOOK;
goto failed;
}
hookset->hooks[hook->code].function = hook->function;
LOG(("out: eb_set_hook() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&hookset->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_set_hook() = %s", eb_error_string(error_code)));
eb_unlock(&hookset->lock);
return error_code;
}
/*
* Set a list of hooks.
*/
EB_Error_Code
eb_set_hooks(EB_Hookset *hookset, const EB_Hook *hook)
{
EB_Error_Code error_code;
const EB_Hook *h;
eb_lock(&hookset->lock);
LOG(("in: eb_set_hooks(hooks=[below])"));
if (eb_log_flag) {
for (h = hook; h->code != EB_HOOK_NULL; h++)
LOG((" hook=%d", h->code));
}
/*
* Set hooks.
*/
for (h = hook; h->code != EB_HOOK_NULL; h++) {
if (h->code < 0 || EB_NUMBER_OF_HOOKS <= h->code) {
error_code = EB_ERR_NO_SUCH_HOOK;
goto failed;
}
hookset->hooks[h->code].function = h->function;
}
/*
* Unlock the hookset.
*/
LOG(("out: eb_set_hooks() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&hookset->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_set_hooks() = %s", eb_error_string(error_code)));
eb_unlock(&hookset->lock);
return error_code;
}
/*
* EUC JP to ASCII conversion table.
*/
#define EUC_TO_ASCII_TABLE_START 0xa0
#define EUC_TO_ASCII_TABLE_END 0xff
static const unsigned char euc_a1_to_ascii_table[] = {
0x00, 0x20, 0x00, 0x00, 0x2c, 0x2e, 0x00, 0x3a, /* 0xa0 */
0x3b, 0x3f, 0x21, 0x00, 0x00, 0x00, 0x60, 0x00, /* 0xa8 */
0x5e, 0x7e, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x2f, /* 0xb8 */
0x5c, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x27, /* 0xc0 */
0x00, 0x22, 0x28, 0x29, 0x00, 0x00, 0x5b, 0x5d, /* 0xc8 */
0x7b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
0x00, 0x00, 0x00, 0x00, 0x2b, 0x2d, 0x00, 0x00, /* 0xd8 */
0x00, 0x3d, 0x00, 0x3c, 0x3e, 0x00, 0x00, 0x00, /* 0xe0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, /* 0xe8 */
0x24, 0x00, 0x00, 0x25, 0x23, 0x26, 0x2a, 0x40, /* 0xf0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8 */
};
static const unsigned char euc_a3_to_ascii_table[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8 */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0xb0 */
0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8 */
0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0xc0 */
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0xc8 */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0xd0 */
0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8 */
0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0xe0 */
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0xe8 */
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0xf0 */
0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8 */
};
/*
* Hook which converts a character from EUC-JP to ASCII.
*/
EB_Error_Code
eb_hook_euc_to_ascii(EB_Book *book, EB_Appendix *appendix, void *container,
EB_Hook_Code hook_code, int argc, const unsigned int *argv)
{
int in_code1, in_code2;
int out_code = 0;
in_code1 = argv[0] >> 8;
in_code2 = argv[0] & 0xff;
if (in_code2 < EUC_TO_ASCII_TABLE_START
|| EUC_TO_ASCII_TABLE_END < in_code2) {
out_code = 0;
} else if (in_code1 == 0xa1) {
out_code = euc_a1_to_ascii_table[in_code2 - EUC_TO_ASCII_TABLE_START];
} else if (in_code1 == 0xa3) {
out_code = euc_a3_to_ascii_table[in_code2 - EUC_TO_ASCII_TABLE_START];
}
if (out_code == 0)
eb_write_text_byte2(book, in_code1, in_code2);
else
eb_write_text_byte1(book, out_code);
return EB_SUCCESS;
}
/*
* Hook for narrow local character.
*/
EB_Error_Code
eb_hook_narrow_character_text(EB_Book *book, EB_Appendix *appendix,
void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv)
{
char alt_text[EB_MAX_ALTERNATION_TEXT_LENGTH + 1];
if (appendix == NULL
|| eb_narrow_alt_character_text(appendix, (int)argv[0], alt_text)
!= EB_SUCCESS) {
eb_write_text_string(book, "<?>");
} else {
eb_write_text_string(book, alt_text);
}
return EB_SUCCESS;
}
/*
* Hook for wide local character.
*/
EB_Error_Code
eb_hook_wide_character_text(EB_Book *book, EB_Appendix *appendix,
void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv)
{
char alt_text[EB_MAX_ALTERNATION_TEXT_LENGTH + 1];
if (appendix == NULL
|| eb_wide_alt_character_text(appendix, (int)argv[0], alt_text)
!= EB_SUCCESS) {
eb_write_text_string(book, "<?>");
} else {
eb_write_text_string(book, alt_text);
}
return EB_SUCCESS;
}
/*
* Hook for a newline character.
*/
EB_Error_Code
eb_hook_newline(EB_Book *book, EB_Appendix *appendix, void *container,
EB_Hook_Code code, int argc, const unsigned int *argv)
{
eb_write_text_byte1(book, '\n');
return EB_SUCCESS;
}
/*
* Hook which does nothing.
*/
EB_Error_Code
eb_hook_empty(EB_Book *book, EB_Appendix *appendix, void *container,
EB_Hook_Code hook_code, int argc, const unsigned int *argv)
{
return EB_SUCCESS;
}

108
jacode.c Normal file
View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
/*
* Convert a string from JIS X 0208 to EUC JP.
*/
void
eb_jisx0208_to_euc(char *out_string, const char *in_string)
{
unsigned char *out_p = (unsigned char *)out_string;
const unsigned char *in_p = (unsigned char *)in_string;
while (*in_p != '\0')
*out_p++ = ((*in_p++) | 0x80);
*out_p = '\0';
}
/*
* Convert a string from shift-JIS to EUC JP.
* (Shift-JIS is used only in the `LANGUAGE' file.)
*/
void
eb_sjis_to_euc(char *out_string, const char *in_string)
{
unsigned char *out_p = (unsigned char *)out_string;
const unsigned char *in_p = (unsigned char *)in_string;
unsigned char c1, c2;
for (;;) {
/*
* Break at '\0'.
*/
c1 = *in_p++;
if (c1 == '\0')
break;
if (c1 <= 0x7f) {
/*
* JIS X 0201 Roman character.
*/
*out_p++ = c1;
} else if (0xa1 <= c1 && c1 <= 0xdf) {
/*
* JIS X 0201 Kana.
*/
*out_p++ = ' ';
} else {
/*
* JIS X 0208 character.
*/
c2 = *in_p++;
if (c2 == 0x00)
break;
if (c2 < 0x9f) {
if (c1 < 0xdf)
c1 = ((c1 - 0x30) << 1) - 1;
else
c1 = ((c1 - 0x70) << 1) - 1;
if (c2 < 0x7f)
c2 += 0x61;
else
c2 += 0x60;
} else {
if (c1 < 0xdf)
c1 = (c1 - 0x30) << 1;
else
c1 = (c1 - 0x70) << 1;
c2 += 0x02;
}
*out_p++ = c1;
*out_p++ = c2;
}
}
*out_p = '\0';
}

189
keyword.c Normal file
View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' supports `KEYWORD SEARCH'
* or not.
*/
int
eb_have_keyword_search(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_keyword_search(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
if (book->subbook_current->keyword.start_page == 0)
goto failed;
LOG(("out: eb_have_keyword_search() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_keyword_search() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Keyword search.
*/
EB_Error_Code
eb_search_keyword(EB_Book *book, const char * const input_words[])
{
EB_Error_Code error_code;
EB_Search_Context *context;
EB_Word_Code word_code;
int word_count;
int i;
/*
* Lock the book.
*/
eb_lock(&book->lock);
LOG(("in: eb_search_keyword(book=%d, input_words=[below])",
(int)book->code));
if (eb_log_flag) {
for (i = 0; i < EB_MAX_KEYWORDS && input_words[i] != NULL; i++) {
LOG((" input_words[%d]=%s", i,
eb_quoted_string(input_words[i])));
}
LOG((" input_words[%d]=NULL", i));
}
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check whether the current subbook has keyword search.
*/
if (book->subbook_current->keyword.start_page == 0) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Attach a search context for each keyword, and pre-search the
* keywords.
*/
eb_reset_search_contexts(book);
word_count = 0;
for (i = 0; i < EB_MAX_KEYWORDS; i++) {
if (input_words[i] == NULL)
break;
/*
* Initialize search context.
*/
context = book->search_contexts + word_count;
context->code = EB_SEARCH_KEYWORD;
/*
* Choose comparison functions.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word;
} else {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word_kana_group;
}
context->page = book->subbook_current->keyword.start_page;
/*
* Make a fixed word and a canonicalized word to search from
* `input_words[i]'.
*/
error_code = eb_set_keyword(book, input_words[i], context->word,
context->canonicalized_word, &word_code);
if (error_code == EB_ERR_EMPTY_WORD)
continue;
else if (error_code != EB_SUCCESS)
goto failed;
/*
* Pre-search.
*/
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS)
goto failed;
word_count++;
}
if (word_count == 0) {
error_code = EB_ERR_NO_WORD;
goto failed;
} else if (EB_MAX_KEYWORDS <= i && input_words[i] != NULL) {
error_code = EB_ERR_TOO_MANY_WORDS;
goto failed;
}
/*
* Set `EB_SEARCH_NONE' to the rest unused search context.
*/
for (i = word_count; i < EB_MAX_KEYWORDS; i++)
(book->search_contexts + i)->code = EB_SEARCH_NONE;
LOG(("out: eb_search_keyword() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_reset_search_contexts(book);
LOG(("out: eb_search_keyword() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

406
linebuf.c Normal file
View File

@ -0,0 +1,406 @@
/*
* copyright (c) 1997-2005 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "linebuf.h"
/*
* Initialize `linebuffer'.
*/
void
initialize_line_buffer(Line_Buffer *line_buffer)
{
line_buffer->buffer[0] = '\0';
line_buffer->file = -1;
line_buffer->cache_length = 0;
line_buffer->timeout = 0;
}
/*
* Finalize `line_buffer'.
*/
void
finalize_line_buffer(Line_Buffer *line_buffer)
{
line_buffer->buffer[0] = '\0';
line_buffer->file = -1;
line_buffer->cache_length = 0;
line_buffer->timeout = 0;
}
/*
* Set timeout seconds.
*/
void
set_line_buffer_timeout(Line_Buffer *line_buffer, int timeout)
{
line_buffer->timeout = timeout;
}
/*
* Bind `file' to `line_buffer'.
*/
void
bind_file_to_line_buffer(Line_Buffer *line_buffer, int file)
{
if (line_buffer->file < 0)
initialize_line_buffer(line_buffer);
line_buffer->file = file;
}
/*
* Return file descriptor bound to `line_buffer'.
* Return -1 when no file is bound.
*/
int
file_bound_to_line_buffer(Line_Buffer *line_buffer)
{
return line_buffer->file;
}
/*
* Discard cache data in `line_buffer'.
*/
void
discard_cache_in_line_buffer(Line_Buffer *line_buffer)
{
line_buffer->cache_length = 0;
}
/*
* Get the length of cache data in `line_buffer'.
*/
size_t
cache_length_in_line_buffer(Line_Buffer *line_buffer)
{
return line_buffer->cache_length;
}
/*
* Read a line from the file bound to `line_buffer', and copy the read
* line to `line'. It reads at most `max_line_length' bytes.
*
* The function recognizes both "\n" and "\r\n" as end of line.
* "\n" or "\r\n" is not copied to `buffer', but "\0" is added, instead.
*
* The function returns the number of characters in the line, upon
* successful. It doesn't count "\n" or "\r\n" in the tail of the line,
* so that 0 is returned for an empty line, and the line length doesn't
* exceed one less than `max_line_length'.
*
* If EOF is received or an error occurs, -1 is returned. If the
* line is too long, `max_line_length' is returned.
*/
ssize_t
read_line_buffer(Line_Buffer *line_buffer, char *line, size_t max_line_length)
{
char *line_p;
char *newline;
size_t search_length;
size_t additional_length;
size_t line_length;
fd_set fdset;
struct timeval timeval;
int select_result;
ssize_t read_result;
/*
* Return -1 if no file is bound, or if `max_line_length' is 0.
*/
if (line_buffer->file < 0)
return -1;
if (max_line_length == 0)
return -1;
/*
* Read a file until newline is appeared.
*/
line_length = 0;
line_p = line;
for (;;) {
if (0 < line_buffer->cache_length) {
/*
* Find a newline in the cache data.
*/
if (max_line_length - line_length < line_buffer->cache_length)
search_length = max_line_length - line_length;
else
search_length = line_buffer->cache_length;
newline = (char *)memchr(line_buffer->buffer, '\n', search_length);
/*
* Append cache data in front of the newline to `line'.
*/
if (newline != NULL)
additional_length = newline - line_buffer->buffer + 1;
else
additional_length = search_length;
memcpy(line_p, line_buffer->buffer, additional_length);
line_p += additional_length;
line_length += additional_length;
line_buffer->cache_length -= additional_length;
/*
* If cache data not copied to `line' are remained in the
* buffer, we move them to the beginning of the buffer.
*/
memmove(line_buffer->buffer,
line_buffer->buffer + additional_length,
line_buffer->cache_length);
if (newline != NULL)
break;
}
/*
* Check for the length of the current line. Return if the
* line is too long.
*
* Note that the following conditional expression can be
* substituted to (line_buffer->cache_length != 0), because
* remained cache data mean that the line is too long.
*/
if (max_line_length <= line_length)
return line_length;
/*
* Call select().
*/
errno = 0;
FD_ZERO(&fdset);
FD_SET(line_buffer->file, &fdset);
if (line_buffer->timeout == 0) {
select_result = select(line_buffer->file + 1, &fdset, NULL, NULL,
NULL);
} else {
timeval.tv_sec = line_buffer->timeout;
timeval.tv_usec = 0;
select_result = select(line_buffer->file + 1, &fdset, NULL, NULL,
&timeval);
}
if (select_result < 0) {
if (errno == EINTR)
continue;
return -1;
} else if (select_result == 0) {
return -1;
}
/*
* Read from a file. (No cache data are remaind.)
*/
errno = 0;
read_result = recv(line_buffer->file, line_buffer->buffer,
LINEBUF_BUFFER_SIZE, 0);
if (read_result < 0) {
if (errno == EINTR)
continue;
return -1;
} else if (read_result == 0) {
if (line_length == 0) {
return -1;
}
return line_length;
}
line_buffer->cache_length += read_result;
}
/*
* Overwrite `\n' with `\0'.
*/
line_p--;
*line_p = '\0';
line_length--;
/*
* If the line is end with `\r\n', remove not only `\n' but `\r'.
*/
if (0 < line_length && *(line_p - 1) == '\r') {
line_p--;
*line_p = '\0';
line_length--;
}
return line_length;
}
/*
* Read just `stream_length' bytes from the file bound to `line_buffer',
* and copy the read bytes to `stream'.
*
* Unlike read_line_buffer(), it doesn't append `\0' to the read data,
* nor remove newline character in the read data.
*
* If it succeeds, the number of bytes actually read is returned.
* If EOF is received or an error occurs, -1 is returned.
*/
ssize_t
binary_read_line_buffer(Line_Buffer *line_buffer, char *stream,
size_t stream_length)
{
char *stream_p;
size_t done_length;
fd_set fdset;
struct timeval timeval;
int select_result;
ssize_t read_result;
/*
* Return -1 if no file is bound.
*/
if (line_buffer->file < 0)
return -1;
/*
* Return 0 if `stream_length' is 0.
*/
if (stream_length == 0)
return 0;
/*
* Test whether cache data are left in `line_buffer->buffer'.
* If they are, copy them to `stream'.
*/
stream_p = stream;
done_length = 0;
if (0 < line_buffer->cache_length) {
if (stream_length <= line_buffer->cache_length)
done_length = stream_length;
else
done_length = line_buffer->cache_length;
memcpy(stream_p, line_buffer->buffer, done_length);
stream_p += done_length;
line_buffer->cache_length -= done_length;
memmove(line_buffer->buffer,
line_buffer->buffer + done_length,
line_buffer->cache_length);
}
/*
* Read the file until the number of read bytes (`done_length') is
* reached to `stream_length'.
*/
while (done_length < stream_length) {
/*
* Call select().
*/
errno = 0;
FD_ZERO(&fdset);
FD_SET(line_buffer->file, &fdset);
if (line_buffer->timeout == 0) {
select_result = select(line_buffer->file + 1, NULL, &fdset, NULL,
NULL);
} else {
timeval.tv_sec = line_buffer->timeout;
timeval.tv_usec = 0;
select_result = select(line_buffer->file + 1, NULL, &fdset, NULL,
&timeval);
}
if (select_result < 0) {
if (errno == EINTR)
continue;
return -1;
} else if (select_result == 0) {
return -1;
}
/*
* Read from a file.
*/
errno = 0;
read_result = recv(line_buffer->file, stream_p,
stream_length - done_length, 0);
if (read_result < 0) {
if (errno == EINTR)
continue;
return read_result;
} else if (read_result == 0) {
if (done_length == 0) {
return -1;
}
return done_length;
}
stream_p += read_result;
done_length += read_result;
}
return stream_length;
}
/*
* Skip too long line read by read_line_buffer().
*
* If a line read by read_line_buffer() doesn't contain a newline
* character, the line is too long. This function reads and discards
* the rest of the line.
*
* If EOF is received or an error occurs, -1 is returned.
* Otherwise, 0 is returned.
*/
int
skip_line_buffer(Line_Buffer *line_buffer)
{
ssize_t line_length;
/*
* Read data until the end of the line is found.
*/
for (;;) {
line_length = read_line_buffer(line_buffer, line_buffer->buffer,
LINEBUF_BUFFER_SIZE);
if (line_length < 0)
return -1;
if (line_length < LINEBUF_BUFFER_SIZE)
break;
}
return 0;
}

66
linebuf.h Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef LINEBUF_H
#define LINEBUF_H
#include <sys/types.h>
/*
* Buffer size of `Line_Buffer' struct.
*/
#define LINEBUF_BUFFER_SIZE 256
/*
* Line buffer manager.
*/
typedef struct {
int file; /* file descriptor */
int timeout; /* idle timeout interval */
size_t cache_length; /* length of cache data */
char buffer[LINEBUF_BUFFER_SIZE]; /* buffer */
} Line_Buffer;
/*
* Function declarations.
*/
void initialize_line_buffer(Line_Buffer *line_buffer);
void finalize_line_buffer(Line_Buffer *line_buffer);
void set_line_buffer_timeout(Line_Buffer *line_buffer, int timeout);
void bind_file_to_line_buffer(Line_Buffer *line_buffer, int file);
int file_bound_to_line_buffer(Line_Buffer *line_buffer);
void discard_cache_in_line_buffer(Line_Buffer *line_buffer);
size_t cache_length_in_line_buffer(Line_Buffer *line_buffer);
ssize_t read_line_buffer(Line_Buffer *line_buffer, char *line,
size_t max_line_length);
ssize_t binary_read_line_buffer(Line_Buffer *line_buffer, char *stream,
size_t stream_length);
int skip_line_buffer(Line_Buffer *line_buffer);
#endif /* not LINEBUF_H */

192
log.c Normal file
View File

@ -0,0 +1,192 @@
/*
* Copyright (c) 2001-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "build-post.h"
#include <stdarg.h>
/*
* Initialization flag.
*/
int eb_log_initialized = 0;
/*
* Debug log flag.
*/
int eb_log_flag = 0;
/*
* Pointer to log function.
*/
static void (*eb_log_function)(const char *message, va_list) = eb_log_stderr;
/*
* Initialize logging sub-system.
*/
void
eb_initialize_log(void)
{
if (eb_log_initialized)
return;
eb_log_flag = (getenv(EB_DEBUG_ENVIRONMENT_VARIABLE) != NULL);
eb_log_function = eb_log_stderr;
eb_log_initialized = 1;
}
/*
* Set log function.
*/
void
eb_set_log_function(void (*function)(const char *message, va_list ap))
{
if (!eb_log_initialized)
eb_initialize_log();
eb_log_function = function;
}
/*
* Enable logging.
*/
void
eb_enable_log(void)
{
if (!eb_log_initialized)
eb_initialize_log();
eb_log_flag = 1;
}
/*
* Disable logging.
*/
void
eb_disable_log(void)
{
if (!eb_log_initialized)
eb_initialize_log();
eb_log_flag = 0;
}
/*
* Log a message.
*/
void
eb_log(const char *message, ...)
{
va_list ap;
va_start(ap, message);
if (eb_log_flag && eb_log_function != NULL)
eb_log_function(message, ap);
va_end(ap);
}
/*
* Output a log message to standard error.
* This is the default log handler.
*
* Currently, this function doesn't work if the system lacks vprintf()
* and dopront().
*/
void
eb_log_stderr(const char *message, va_list ap)
{
pthread_mutex_lock(&log_mutex);
fputs("[EB] ", stderr);
vfprintf(stderr, message, ap);
fputc('\n', stderr);
fflush(stderr);
pthread_mutex_unlock(&log_mutex);
}
#define MAX_QUOTED_STREAM_LENGTH 100
/*
* Return Quoted printable string of `stream'.
*/
const char *
eb_quoted_stream(const char *stream, size_t stream_length)
{
static char quoted_streams[EB_MAX_KEYWORDS][MAX_QUOTED_STREAM_LENGTH + 3];
static int current_index = 0;
unsigned char *quoted_p;
const unsigned char *stream_p;
size_t quoted_length = 0;
int i;
current_index = (current_index + 1) % EB_MAX_KEYWORDS;
quoted_p = (unsigned char *)quoted_streams[current_index];
stream_p = (const unsigned char *)stream;
if (stream == NULL)
return "";
for (i = 0; i < stream_length && *stream_p != '\0'; i++) {
if (0x20 <= *stream_p && *stream_p <= 0x7f && *stream_p != '=') {
if (MAX_QUOTED_STREAM_LENGTH < quoted_length + 1) {
*quoted_p++ = '.';
*quoted_p++ = '.';
break;
}
*quoted_p++ = *stream_p;
quoted_length++;
} else {
if (MAX_QUOTED_STREAM_LENGTH < quoted_length + 3) {
*quoted_p++ = '.';
*quoted_p++ = '.';
break;
}
*quoted_p++ = '=';
*quoted_p++ = "0123456789ABCDEF" [*stream_p / 0x10];
*quoted_p++ = "0123456789ABCDEF" [*stream_p % 0x10];
quoted_length += 3;
}
stream_p++;
}
*quoted_p = '\0';
return quoted_streams[current_index];
}
/*
* Return Quoted printable string.
*/
const char *
eb_quoted_string(const char *string)
{
return eb_quoted_stream(string, strlen(string));
}

583
match.c Normal file
View File

@ -0,0 +1,583 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "build-post.h"
/*
* Compare `word' and `pattern'.
* `word' must be terminated by `\0' and `pattern' is assumed to be
* `length' characters long.
*
* When `word' is equal to `pattern', or equal to the beginning of
* `pattern', 0 is returned. A positive or negateive integer is
* returned according as `pattern' is greater or less than `word'.
*/
int
eb_match_word(const char *word, const char *pattern, size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
int result;
LOG(("in: eb_match_word(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
result = 0;
break;
}
if (*word_p != *pattern_p) {
result = *word_p - *pattern_p;
break;
}
word_p++;
pattern_p++;
i++;
}
LOG(("out: eb_match_word() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' for pre-search.
* `word' must be terminated by `\0' and `pattern' is assumed to be
* `length' characters long.
*
* When `word' is equal to `pattern', or equal to the beginning of
* `pattern', 0 is returned. A positive or negateive integer is
* returned according as `pattern' is greater or less than `word'.
*/
int
eb_pre_match_word(const char *word, const char *pattern, size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
int result;
LOG(("in: eb_pre_match_word(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = 0;
break;
}
if (*word_p == '\0') {
result = 0;
break;
}
if (*word_p != *pattern_p) {
result = *word_p - *pattern_p;
break;
}
word_p++;
pattern_p++;
i++;
}
LOG(("out: eb_pre_match_word() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in JIS X 0208.
* `word' must be terminated by `\0' and `pattern' is assumed to be
* `length' characters long.
*
* When the word is equal to the pattern, 0 is returned. A positive or
* negateive integer is returned according as `pattern' is greater or
* less than `word'.
*/
int
eb_exact_match_word_jis(const char *word, const char *pattern, size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
int result;
LOG(("in: eb_exact_match_word_jis(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
/* ignore spaces in the tail of the pattern */
while (i < length && *pattern_p == '\0') {
pattern_p++;
i++;
}
result = (i - length);
break;
}
if (*word_p != *pattern_p) {
result = *word_p - *pattern_p;
break;
}
word_p++;
pattern_p++;
i++;
}
LOG(("out: eb_exact_match_word_jis() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in JIS X 0208 for pre-search.
* `word' must be terminated by `\0' and `pattern' is assumed to be
* `length' characters long.
*
* When the word is equal to the pattern, 0 is returned. A positive or
* negateive integer is returned according as `pattern' is greater or
* less than `word'.
*/
int
eb_exact_pre_match_word_jis(const char *word, const char *pattern,
size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
int result;
LOG(("in: eb_exact_pre_match_word_jis(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = 0;
break;
}
if (*word_p == '\0') {
/* ignore spaces in the tail of the pattern */
while (i < length && *pattern_p == '\0') {
pattern_p++;
i++;
}
result = (i - length);
break;
}
if (*word_p != *pattern_p) {
result = *word_p - *pattern_p;
break;
}
word_p++;
pattern_p++;
i++;
}
LOG(("out: eb_exact_pre_match_word_jis() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in Latin1.
* `word' must be terminated by `\0' and `pattern' is assumed to be
* `length' characters long.
*
* When the word is equal to the pattern, 0 is returned. A positive or
* negateive integer is returned according as `pattern' is greater or
* less than `word'.
*/
int
eb_exact_match_word_latin(const char *word, const char *pattern, size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
int result;
LOG(("in: eb_exact_match_word_latin(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
/* ignore spaces in the tail of the pattern */
while (i < length && (*pattern_p == ' ' || *pattern_p == '\0')) {
pattern_p++;
i++;
}
result = (i - length);
break;
}
if (*word_p != *pattern_p) {
result = *word_p - *pattern_p;
break;
}
word_p++;
pattern_p++;
i++;
}
LOG(("out: eb_exact_match_word_latin() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in Latin1 for pre-search.
* `word' must be terminated by `\0' and `pattern' is assumed to be
* `length' characters long.
*
* When the word is equal to the pattern, 0 is returned. A positive or
* negateive integer is returned according as `pattern' is greater or
* less than `word'.
*/
int
eb_exact_pre_match_word_latin(const char *word, const char *pattern,
size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
int result;
LOG(("in: eb_exact_pre_match_word_latin(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = 0;
break;
}
if (*word_p == '\0') {
/* ignore spaces in the tail of the pattern */
while (i < length && (*pattern_p == ' ' || *pattern_p == '\0')) {
pattern_p++;
i++;
}
result = (i - length);
break;
}
if (*word_p != *pattern_p) {
result = *word_p - *pattern_p;
break;
}
word_p++;
pattern_p++;
i++;
}
LOG(("out: eb_exact_pre_match_word_latin() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in JIS X 0208.
*
* This function is equivalent to eb_match_word() except that this function
* ignores differences of kana (katakana and hiragana). The order of
* hiragana and katakana characters is:
*
* If `word' and `pattern' differ, the function compares their characters
* with the following rule:
*
* HIRAGANA `KA' < HIRAGANA `GA' < KATAKANA `KA' < KATAKANA `GA'
*/
int
eb_match_word_kana_group(const char *word, const char *pattern, size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
unsigned char wc0, wc1, pc0, pc1;
int result;
LOG(("in: eb_match_word_kana_group(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
result = 0;
break;
}
if (length <= i + 1 || *(word_p + 1) == '\0') {
result = *word_p - *pattern_p;
break;
}
wc0 = *word_p;
wc1 = *(word_p + 1);
pc0 = *pattern_p;
pc1 = *(pattern_p + 1);
if ((wc0 == 0x24 || wc0 == 0x25) && (pc0 == 0x24 || pc0 == 0x25)) {
if (wc1 != pc1) {
result = ((wc0 << 8) + wc1) - ((pc0 << 8) + pc1);
break;
}
} else {
if (wc0 != pc0 || wc1 != pc1) {
result = ((wc0 << 8) + wc1) - ((pc0 << 8) + pc1);
break;
}
}
word_p += 2;
pattern_p += 2;
i += 2;
}
LOG(("out: eb_match_word_kana_group() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in JIS X 0208.
*
* This function is equivalent to eb_match_word() except that this function
* ignores differences of kana (katakana and hiragana). The order of
* hiragana and katakana characters is:
*
* If `word' and `pattern' differ, the function compares their characters
* with the following rule:
*
* HIRAGANA `KA' == KATAKANA `KA' < HIRAGANA `GA' == KATAKANA `GA'.
*/
int
eb_match_word_kana_single(const char *word, const char *pattern, size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
unsigned char wc0, wc1, pc0, pc1;
int result;
LOG(("in: eb_match_word_kana_single(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
result = 0;
break;
}
if (length <= i + 1 || *(word_p + 1) == '\0') {
result = *word_p - *pattern_p;
break;
}
wc0 = *word_p;
wc1 = *(word_p + 1);
pc0 = *pattern_p;
pc1 = *(pattern_p + 1);
if ((wc0 == 0x24 || wc0 == 0x25) && (pc0 == 0x24 || pc0 == 0x25)) {
if (wc1 != pc1) {
result = wc1 - pc1;
break;
}
} else {
if (wc0 != pc0 || wc1 != pc1) {
result = ((wc0 << 8) + wc1) - ((pc0 << 8) + pc1);
break;
}
}
word_p += 2;
pattern_p += 2;
i += 2;
}
LOG(("out: eb_match_word_kana_single() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in JIS X 0208.
*
* This function is equivalent to eb_exact_match_word_jis() except that
* this function ignores differences of kana (katakana and hiragana).
*
* If `word' and `pattern' differ, the function compares their characters
* with the following rule:
*
* HIRAGANA `KA' < HIRAGANA `GA' < KATAKANA `KA' < KATAKANA `GA'
*/
int
eb_exact_match_word_kana_group(const char *word, const char *pattern,
size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
unsigned char wc0, wc1, pc0, pc1;
int result;
LOG(("in: eb_exact_match_word_kana_group(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
result = - *pattern_p;
break;
}
if (length <= i + 1 || *(word_p + 1) == '\0') {
result = *word_p - *pattern_p;
break;
}
wc0 = *word_p;
wc1 = *(word_p + 1);
pc0 = *pattern_p;
pc1 = *(pattern_p + 1);
if ((wc0 == 0x24 || wc0 == 0x25) && (pc0 == 0x24 || pc0 == 0x25)) {
if (wc1 != pc1) {
result = ((wc0 << 8) + wc1) - ((pc0 << 8) + pc1);
break;
}
} else {
if (wc0 != pc0 || wc1 != pc1) {
result = ((wc0 << 8) + wc1) - ((pc0 << 8) + pc1);
break;
}
}
word_p += 2;
pattern_p += 2;
i += 2;
}
LOG(("out: eb_exact_match_word_kana_group() = %d", result));
return result;
}
/*
* Compare `word' and `pattern' in JIS X 0208.
*
* This function is equivalent to eb_exact_match_word_jis() except that
* this function ignores differences of kana (katakana and hiragana).
* The order of hiragana and katakana characters is:
*
* If `word' and `pattern' differ, the function compares their characters
* with the following rule:
*
* HIRAGANA `KA' == KATAKANA `KA' < HIRAGANA `GA' == KATAKANA `GA'.
*/
int
eb_exact_match_word_kana_single(const char *word, const char *pattern,
size_t length)
{
int i = 0;
unsigned char *word_p = (unsigned char *)word;
unsigned char *pattern_p = (unsigned char *)pattern;
unsigned char wc0, wc1, pc0, pc1;
int result;
LOG(("in: eb_exact_match_word_kana_single(word=%s, pattern=%s)",
eb_quoted_stream(word, EB_MAX_WORD_LENGTH),
eb_quoted_stream(pattern, length)));
for (;;) {
if (length <= i) {
result = *word_p;
break;
}
if (*word_p == '\0') {
result = - *pattern_p;
break;
}
if (length <= i + 1 || *(word_p + 1) == '\0') {
result = *word_p - *pattern_p;
break;
}
wc0 = *word_p;
wc1 = *(word_p + 1);
pc0 = *pattern_p;
pc1 = *(pattern_p + 1);
if ((wc0 == 0x24 || wc0 == 0x25) && (pc0 == 0x24 || pc0 == 0x25)) {
if (wc1 != pc1) {
result = wc1 - pc1;
break;
}
} else {
if (wc0 != pc0 || wc1 != pc1) {
result = ((wc0 << 8) + wc1) - ((pc0 << 8) + pc1);
break;
}
}
word_p += 2;
pattern_p += 2;
i += 2;
}
LOG(("out: eb_exact_match_word_kana_single() = %d", result));
return result;
}

206
menu.c Normal file
View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' supports `MENU SEARCH'
* or not.
*/
int
eb_have_menu(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_menu(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* Check for the index page of menu search.
*/
if (book->subbook_current->menu.start_page == 0)
goto failed;
LOG(("out: eb_have_menu() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_menu() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Menu.
*/
EB_Error_Code
eb_menu(EB_Book *book, EB_Position *position)
{
EB_Error_Code error_code;
int page;
eb_lock(&book->lock);
LOG(("in: eb_menu(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check for the page number of menu search.
*/
page = book->subbook_current->menu.start_page;
if (page == 0) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Copy the position to `position'.
*/
position->page = page;
position->offset = 0;
LOG(("out: eb_menu(position={%d,%d}) = %s",
position->page, position->offset, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_menu() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Examine whether the current subbook in `book' supports `GRAPHIC MENU SEARCH'
* or not.
*/
int
eb_have_image_menu(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_image_menu(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* Check for the index page of graphic menu search.
*/
if (book->subbook_current->image_menu.start_page == 0)
goto failed;
LOG(("out: eb_have_image_menu() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_image_menu() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Graphic Menu.
*/
EB_Error_Code
eb_image_menu(EB_Book *book, EB_Position *position)
{
EB_Error_Code error_code;
int page;
eb_lock(&book->lock);
LOG(("in: eb_image_menu(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check for the page number of graphic menu search.
*/
page = book->subbook_current->image_menu.start_page;
if (page == 0) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Copy the position to `position'.
*/
position->page = page;
position->offset = 0;
LOG(("out: eb_image_menu(position={%d,%d}) = %s",
position->page, position->offset, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_image_menu() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

839
multi.c Normal file
View File

@ -0,0 +1,839 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Get information about the current subbook.
*/
EB_Error_Code
eb_load_multi_searches(EB_Book *book)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Multi_Search *multi;
EB_Search *entry;
char buffer[EB_SIZE_PAGE];
char *buffer_p;
int index_count;
int index_id;
int i, j, k;
LOG(("in: eb_load_multi_searches(book=%d)", book->code));
subbook = book->subbook_current;
for (i = 0, multi = subbook->multis; i < subbook->multi_count;
i++, multi++) {
/*
* Read the index table page of the multi search.
*/
if (zio_lseek(&subbook->text_zio,
((off_t) multi->search.start_page - 1) * EB_SIZE_PAGE, SEEK_SET)
< 0) {
error_code = EB_ERR_FAIL_SEEK_TEXT;
goto failed;
}
if (zio_read(&subbook->text_zio, buffer, EB_SIZE_PAGE)
!= EB_SIZE_PAGE) {
error_code = EB_ERR_FAIL_READ_TEXT;
goto failed;
}
/*
* Get the number of entries in this multi search.
*/
multi->entry_count = eb_uint2(buffer);
if (EB_MAX_MULTI_SEARCHES <= multi->entry_count) {
error_code = EB_ERR_UNEXP_TEXT;
goto failed;
}
buffer_p = buffer + 16;
for (j = 0, entry = multi->entries;
j < multi->entry_count; j++, entry++) {
/*
* Get the number of indexes in this entry, and title
* of this entry.
*/
index_count = eb_uint1(buffer_p);
strncpy(entry->label, buffer_p + 2, EB_MAX_MULTI_LABEL_LENGTH);
entry->label[EB_MAX_MULTI_LABEL_LENGTH] = '\0';
eb_jisx0208_to_euc(entry->label, entry->label);
buffer_p += EB_MAX_MULTI_LABEL_LENGTH + 2;
/*
* Initialize index page information of the entry.
*/
for (k = 0; k < index_count; k++) {
/*
* Get the index page information of the entry.
*/
index_id = eb_uint1(buffer_p);
switch (index_id) {
case 0x71:
case 0x91:
case 0xa1:
if (entry->start_page != 0 && entry->index_id != 0x71)
break;
entry->start_page = eb_uint4(buffer_p + 2);
entry->end_page = entry->start_page
+ eb_uint4(buffer_p + 6) - 1;
entry->index_id = index_id;
entry->katakana = EB_INDEX_STYLE_ASIS;
entry->lower = EB_INDEX_STYLE_CONVERT;
entry->mark = EB_INDEX_STYLE_ASIS;
entry->long_vowel = EB_INDEX_STYLE_ASIS;
entry->double_consonant = EB_INDEX_STYLE_ASIS;
entry->contracted_sound = EB_INDEX_STYLE_ASIS;
entry->voiced_consonant = EB_INDEX_STYLE_ASIS;
entry->small_vowel = EB_INDEX_STYLE_ASIS;
entry->p_sound = EB_INDEX_STYLE_ASIS;
entry->space = EB_INDEX_STYLE_ASIS;
break;
case 0x01:
entry->candidates_page = eb_uint4(buffer_p + 2);
break;
}
buffer_p += 16;
}
}
}
LOG(("out: eb_load_multi_searches() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_multi_searches() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Default multi search titles (written in JIS X 0208).
*/
static const char *default_multi_titles_jisx0208[] = {
"J#9g8!:w#1", /* Multi search 1. */
"J#9g8!:w#2", /* Multi search 2. */
"J#9g8!:w#3", /* Multi search 3. */
"J#9g8!:w#4", /* Multi search 4. */
"J#9g8!:w#5", /* Multi search 5. */
"J#9g8!:w#6", /* Multi search 6. */
"J#9g8!:w#7", /* Multi search 7. */
"J#9g8!:w#8", /* Multi search 8. */
"J#9g8!:w#9", /* Multi search 9. */
"J#9g8!:w#1#0", /* Multi search 10. */
};
/*
* Default multi search titles (written in ASCII, subset of ISO 8859-1).
*/
static const char *default_multi_titles_latin[] = {
"Multi search 1",
"Multi search 2",
"Multi search 3",
"Multi search 4",
"Multi search 5",
"Multi search 6",
"Multi search 7",
"Multi search 8",
"Multi search 9",
"Multi search 10",
};
/*
* Load multi search titles.
*/
EB_Error_Code
eb_load_multi_titles(EB_Book *book)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
char buffer[EB_SIZE_PAGE];
int title_count;
char *title;
size_t offset;
int i;
LOG(("in: eb_load_multi_searches(book=%d)", book->code));
subbook = book->subbook_current;
/*
* Set default titles.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
for (i = 0; i < subbook->multi_count; i++) {
title = subbook->multis[i].title;
strcpy(title, default_multi_titles_latin[i]);
}
} else {
for (i = 0; i < subbook->multi_count; i++) {
title = subbook->multis[i].title;
strcpy(title, default_multi_titles_jisx0208[i]);
eb_jisx0208_to_euc(title, title);
}
}
if (book->disc_code != EB_DISC_EPWING || subbook->search_title_page == 0)
goto succeeded;
/*
* Read the page of the multi search.
*/
if (zio_lseek(&subbook->text_zio,
((off_t) subbook->search_title_page - 1) * EB_SIZE_PAGE, SEEK_SET)
< 0) {
error_code = EB_ERR_FAIL_SEEK_TEXT;
goto failed;
}
if (zio_read(&subbook->text_zio, buffer, EB_SIZE_PAGE) != EB_SIZE_PAGE) {
error_code = EB_ERR_FAIL_READ_TEXT;
goto failed;
}
title_count = eb_uint2(buffer);
if (EB_MAX_SEARCH_TITLES < title_count)
title_count = EB_MAX_SEARCH_TITLES;
/*
* We need titles for multi searches only.
* titles[ 0]: title for word and endword searches.
* titles[ 1]: title for keyword search.
* titles[ 2]: common title for all multi searches.
* (we don't need this)
* titles[ 3]: title for multi search 1.
* :
* titles[12]: title for multi search 10.
* titles[13]: title for menu search.
*
* The offset of titles[3] is:
* the number of entries(2bytes)
* + reserved 1 (68bytes)
* + title for word and endword searches (70bytes)
* + title for keyword search (70bytes)
* + common title for all multi searches (70bytes)
* + reserved 2 (70bytes)
* = 2 + 68 + 70 + 70 + 70 + 70 = 350
*/
for (i = 4, offset = 350; i < EB_MAX_SEARCH_TITLES; i++, offset += 70) {
if (subbook->multi_count <= i - 4)
break;
if (eb_uint2(buffer + offset) != 0x02)
continue;
/*
* Each titles[] consists of
* parameter (2bytes)
* short title (16bytes)
* long title (32bytes)
* We get long title rather than short one.
*/
title = subbook->multis[i - 4].title;
strncpy(title, buffer + offset + 2 + 16, EB_MAX_MULTI_TITLE_LENGTH);
title[EB_MAX_MULTI_TITLE_LENGTH] = '\0';
eb_jisx0208_to_euc(title, title);
}
succeeded:
LOG(("out: eb_load_multi_titles() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_multi_titles() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Examine whether the current subbook in `book' supports `MULTI SEARCH'
* or not.
*/
int
eb_have_multi_search(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_multi_search(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
if (book->subbook_current->multi_count == 0)
goto failed;
LOG(("out: eb_have_multi_search() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_multi_search() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Return a title of the multi search `multi_id'.
*/
EB_Error_Code
eb_multi_title(EB_Book *book, EB_Multi_Search_Code multi_id, char *title)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
eb_lock(&book->lock);
LOG(("in: eb_multi_title(book=%d, multi_id=%d)",
(int)book->code, (int)multi_id));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Current subbook must have been set.
*/
subbook = book->subbook_current;
if (subbook == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* `multi_id' must be a valid code.
*/
if (multi_id < 0 || subbook->multi_count <= multi_id) {
error_code = EB_ERR_NO_SUCH_MULTI_ID;
goto failed;
}
strcpy(title, subbook->multis[multi_id].title);
LOG(("out: eb_multi_title(title=%s) = %s", title,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*title = '\0';
LOG(("out: eb_multi_title() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Return a list of multi search ids in `book'.
*/
EB_Error_Code
eb_multi_search_list(EB_Book *book, EB_Multi_Search_Code *search_list,
int *search_count)
{
EB_Error_Code error_code;
EB_Subbook_Code *list_p;
int i;
eb_lock(&book->lock);
LOG(("in: eb_multi_search_list(book=%d)", (int)book->code));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
*search_count = book->subbook_current->multi_count;
for (i = 0, list_p = search_list; i < *search_count; i++, list_p++)
*list_p = i;
LOG(("out: eb_multi_search_list(search_count=%d) = %s", *search_count,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*search_count = 0;
LOG(("out: eb_multi_search_list() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Return the number of entries that the multi search `multi_id' in `book'.
*/
EB_Error_Code
eb_multi_entry_count(EB_Book *book, EB_Multi_Search_Code multi_id,
int *entry_count)
{
EB_Error_Code error_code;
eb_lock(&book->lock);
LOG(("in: eb_multi_entry_count(book=%d, multi_id=%d)", (int)book->code,
(int)multi_id));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* `multi_id' must be a valid code.
*/
if (multi_id < 0 || book->subbook_current->multi_count <= multi_id) {
error_code = EB_ERR_NO_SUCH_MULTI_ID;
goto failed;
}
*entry_count = book->subbook_current->multis[multi_id].entry_count;
LOG(("out: eb_multi_entry_count(entry_count=%d) = %s", (int)*entry_count,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*entry_count = 0;
LOG(("out: eb_multi_entry_count() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Return a list of entries that the multi search `multi_id' in `book' has.
* (Legacy function)
*/
EB_Error_Code
eb_multi_entry_list(EB_Book *book, EB_Multi_Search_Code multi_id,
int *entry_list, int *entry_count)
{
EB_Error_Code error_code;
EB_Subbook_Code *list_p;
int i;
error_code = eb_multi_entry_count(book, multi_id, entry_count);
if (error_code != EB_SUCCESS)
return error_code;
for (i = 0, list_p = entry_list; i < *entry_count; i++, list_p++)
*list_p = i;
return EB_SUCCESS;
}
/*
* Return a lable of the entry `entry_index' in the multi search `multi_id'.
*/
EB_Error_Code
eb_multi_entry_label(EB_Book *book, EB_Multi_Search_Code multi_id,
int entry_index, char *label)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
eb_lock(&book->lock);
LOG(("in: eb_multi_entry_label(book=%d, multi_id=%d, entry_index=%d)",
(int)book->code, (int)multi_id, entry_index));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Current subbook must have been set.
*/
subbook = book->subbook_current;
if (subbook == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* `multi_id' must be a valid code.
*/
if (multi_id < 0 || subbook->multi_count <= multi_id) {
error_code = EB_ERR_NO_SUCH_MULTI_ID;
goto failed;
}
/*
* `entry_index' must be a valid code.
*/
if (entry_index < 0
|| subbook->multis[multi_id].entry_count <= entry_index) {
error_code = EB_ERR_NO_SUCH_ENTRY_ID;
goto failed;
}
strcpy(label, subbook->multis[multi_id].entries[entry_index].label);
LOG(("out: eb_multi_entry_label(label=%s) = %s", label,
eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*label = '\0';
LOG(("out: eb_multi_entry_label() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Whether the entry `entry_index' in the multi search `multi_id' has
* candidates or not.
*/
int
eb_multi_entry_have_candidates(EB_Book *book, EB_Multi_Search_Code multi_id,
int entry_index)
{
EB_Multi_Search *multi;
eb_lock(&book->lock);
LOG(("in: eb_multi_entry_have_candidates(book=%d, multi_id=%d, \
entry_index=%d)",
(int)book->code, (int)multi_id, entry_index));
/*
* The book must have been bound.
*/
if (book->path == NULL)
goto failed;
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* `multi_id' must be a valid code.
*/
if (multi_id < 0 || book->subbook_current->multi_count <= multi_id)
goto failed;
/*
* `entry_index' must be a valid code.
*/
multi = book->subbook_current->multis + multi_id;
if (entry_index < 0 || multi->entry_count <= entry_index)
goto failed;
if (multi->entries[entry_index].candidates_page == 0)
goto failed;
LOG(("out: eb_multi_entry_have_candidates() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_multi_entry_have_candidates() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Return a position of candidates for the entry `entry_index' in the multi
* search `multi_id'.
*/
EB_Error_Code
eb_multi_entry_candidates(EB_Book *book, EB_Multi_Search_Code multi_id,
int entry_index, EB_Position *position)
{
EB_Error_Code error_code;
EB_Multi_Search *multi;
eb_lock(&book->lock);
LOG(("in: eb_multi_entry_candidates(book=%d, multi_id=%d, entry_index=%d)",
(int)book->code, (int)multi_id, entry_index));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
}
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* `multi_id' must be a valid code.
*/
if (multi_id < 0 || book->subbook_current->multi_count <= multi_id) {
error_code = EB_ERR_NO_SUCH_MULTI_ID;
goto failed;
}
/*
* `entry_index' must be a valid code.
*/
multi = book->subbook_current->multis + multi_id;
if (entry_index < 0 || multi->entry_count <= entry_index) {
error_code = EB_ERR_NO_SUCH_ENTRY_ID;
goto failed;
}
if (multi->entries[entry_index].candidates_page == 0) {
error_code = EB_ERR_NO_CANDIDATES;
goto failed;
}
position->page = multi->entries[entry_index].candidates_page;
position->offset = 0;
LOG(("out: eb_multi_entry_candidates(position={%d,%d}) = %s",
position->page, position->offset, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_multi_entry_candidates() = %s",
eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}
/*
* Multi search.
*/
EB_Error_Code
eb_search_multi(EB_Book *book, EB_Multi_Search_Code multi_id,
const char * const input_words[])
{
EB_Error_Code error_code;
EB_Search_Context *context;
EB_Search *entry;
EB_Word_Code word_code;
int word_count;
int i;
eb_lock(&book->lock);
LOG(("in: eb_search_multi(book=%d, multi_id=%d, input_words=[below])",
(int)book->code, (int)multi_id));
if (eb_log_flag) {
for (i = 0; i < EB_MAX_KEYWORDS && input_words[i] != NULL; i++) {
LOG((" input_words[%d]=%s", i,
eb_quoted_string(input_words[i])));
}
LOG((" input_words[%d]=NULL", i));
}
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check whether the current subbook has keyword search.
*/
if (multi_id < 0 || book->subbook_current->multi_count <= multi_id) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Attach a search context for each keyword, and pre-search the
* keywords.
*/
eb_reset_search_contexts(book);
word_count = 0;
for (i = 0, entry = book->subbook_current->multis[multi_id].entries;
i < book->subbook_current->multis[multi_id].entry_count;
i++, entry++) {
if (input_words[i] == NULL)
break;
/*
* Initialize search context.
*/
context = book->search_contexts + word_count;
context->code = EB_SEARCH_MULTI;
/*
* Choose comparison functions.
*/
if (entry->candidates_page == 0) {
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word;
} else {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word_kana_group;
}
} else {
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_exact_pre_match_word_latin;
context->compare_single = eb_exact_match_word_latin;
context->compare_group = eb_exact_match_word_latin;
} else {
context->compare_pre = eb_exact_pre_match_word_jis;
context->compare_single = eb_exact_match_word_jis;
context->compare_group = eb_exact_match_word_kana_group;
}
}
context->page = entry->start_page;
if (context->page == 0)
continue;
/*
* Make a fixed word and a canonicalized word to search from
* `input_words[i]'.
*/
error_code = eb_set_multiword(book, multi_id, i, input_words[i],
context->word, context->canonicalized_word, &word_code);
if (error_code == EB_ERR_EMPTY_WORD)
continue;
else if (error_code != EB_SUCCESS)
goto failed;
/*
* Pre-search.
*/
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS)
goto failed;
word_count++;
}
if (word_count == 0) {
error_code = EB_ERR_NO_WORD;
goto failed;
} else if (book->subbook_current->multis[multi_id].entry_count <= i
&& input_words[i] != NULL) {
error_code = EB_ERR_TOO_MANY_WORDS;
goto failed;
}
/*
* Set `EB_SEARCH_NONE' to the rest unused search context.
*/
for (i = word_count; i < EB_MAX_KEYWORDS; i++)
(book->search_contexts + i)->code = EB_SEARCH_NONE;
LOG(("out: eb_search_multi() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_reset_search_contexts(book);
LOG(("out: eb_search_multi() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

626
narwalt.c Normal file
View File

@ -0,0 +1,626 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "appendix.h"
#include "build-post.h"
/*
* Unexported functions.
*/
static EB_Error_Code eb_narrow_character_text_jis(EB_Appendix *appendix,
int character_number, char *text);
static EB_Error_Code eb_narrow_character_text_latin(EB_Appendix *appendix,
int character_number, char *text);
/*
* Hash macro for cache data.
*/
#define EB_HASH_ALT_CACHE(c) ((c) & 0x0f)
/*
* Examine whether the current subbook in `book' has a narrow font
* alternation or not.
*/
int
eb_have_narrow_alt(EB_Appendix *appendix)
{
eb_lock(&appendix->lock);
LOG(("in: eb_have_narrow_alt(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL)
goto failed;
if (appendix->subbook_current->narrow_page == 0)
goto failed;
LOG(("out: eb_have_narrow_alt() = %d", 1));
eb_unlock(&appendix->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_narrow_alt() = %d", 0));
eb_unlock(&appendix->lock);
return 0;
}
/*
* Look up the character number of the start of the narrow font alternation
* of the current subbook in `book'.
*/
EB_Error_Code
eb_narrow_alt_start(EB_Appendix *appendix, int *start)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_narrow_alt_start(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
if (appendix->subbook_current->narrow_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
*start = appendix->subbook_current->narrow_start;
LOG(("out: eb_narrow_alt_start(start=%d) = %s", *start,
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*start = -1;
LOG(("out: eb_narrow_alt_start() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Return the character number of the end of the narrow font alternation
* of the current subbook in `book'.
*/
EB_Error_Code
eb_narrow_alt_end(EB_Appendix *appendix, int *end)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_narrow_alt_end(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
if (appendix->subbook_current->narrow_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
*end = appendix->subbook_current->narrow_end;
LOG(("out: eb_narrow_alt_end(end=%d) = %s", *end,
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*end = -1;
LOG(("out: eb_narrow_alt_end() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the alternation text of the character number `character_number'.
*/
EB_Error_Code
eb_narrow_alt_character_text(EB_Appendix *appendix, int character_number,
char *text)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_narrow_alt_character_text(appendix=%d, character_number=%d)",
(int)appendix->code, character_number));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* The narrow font must exist in the current subbook.
*/
if (appendix->subbook_current->narrow_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
if (appendix->subbook_current->character_code == EB_CHARCODE_ISO8859_1) {
error_code = eb_narrow_character_text_latin(appendix,
character_number, text);
} else {
error_code = eb_narrow_character_text_jis(appendix, character_number,
text);
}
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_narrow_alt_character_text(text=%s) = %s",
eb_quoted_string(text), eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*text = '\0';
LOG(("out: eb_narrow_alt_character_text() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the alternation text of the character number `character_number'.
*/
static EB_Error_Code
eb_narrow_character_text_jis(EB_Appendix *appendix, int character_number,
char *text)
{
EB_Error_Code error_code;
int start;
int end;
off_t location;
EB_Alternation_Cache *cachep;
LOG(("in: eb_narrow_alt_character_text_jis(appendix=%d, \
character_number=%d)",
(int)appendix->code, character_number));
start = appendix->subbook_current->narrow_start;
end = appendix->subbook_current->narrow_end;
/*
* Check for `character_number'. Is it in a font?
* This test works correctly even when the font doesn't exist in
* the current subbook because `start' and `end' have set to -1
* in the case.
*/
if (character_number < start
|| end < character_number
|| (character_number & 0xff) < 0x21
|| 0x7e < (character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Calculate the location of alternation data.
*/
location
= (appendix->subbook_current->narrow_page - 1) * EB_SIZE_PAGE
+ (((character_number >> 8) - (start >> 8)) * 0x5e
+ (character_number & 0xff) - (start & 0xff))
* (EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
/*
* Check for the cache data.
*/
cachep = appendix->narrow_cache + EB_HASH_ALT_CACHE(character_number);
if (cachep->character_number == character_number) {
memcpy(text, cachep->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
goto succeeded;
}
/*
* Read the alternation data.
*/
if (zio_lseek(&appendix->subbook_current->zio, location, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
cachep->character_number = -1;
if (zio_read(&appendix->subbook_current->zio, cachep->text,
EB_MAX_ALTERNATION_TEXT_LENGTH + 1)
!= EB_MAX_ALTERNATION_TEXT_LENGTH + 1) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
/*
* Update cache data.
*/
memcpy(text, cachep->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
cachep->text[EB_MAX_ALTERNATION_TEXT_LENGTH] = '\0';
cachep->character_number = character_number;
succeeded:
LOG(("out: eb_narrow_alt_character_text_jis(text=%s) = %s",
eb_quoted_string(text), eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*text = '\0';
LOG(("out: eb_narrow_alt_character_text_jis() = %s",
eb_error_string(error_code)));
return error_code;
}
/*
* Get the alternation text of the character number `character_number'.
*/
static EB_Error_Code
eb_narrow_character_text_latin(EB_Appendix *appendix, int character_number,
char *text)
{
EB_Error_Code error_code;
int start;
int end;
off_t location;
EB_Alternation_Cache *cache_p;
LOG(("in: eb_narrow_alt_character_text_latin(appendix=%d, \
character_number=%d)",
(int)appendix->code, character_number));
start = appendix->subbook_current->narrow_start;
end = appendix->subbook_current->narrow_end;
/*
* Check for `character_number'. Is it in a font?
* This test works correctly even when the font doesn't exist in
* the current subbook because `start' and `end' have set to -1
* in the case.
*/
if (character_number < start
|| end < character_number
|| (character_number & 0xff) < 0x01
|| 0xfe < (character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Calculate the location of alternation data.
*/
location
= (appendix->subbook_current->narrow_page - 1) * EB_SIZE_PAGE
+ (((character_number >> 8) - (start >> 8)) * 0xfe
+ (character_number & 0xff) - (start & 0xff))
* (EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
/*
* Check for the cache data.
*/
cache_p = appendix->narrow_cache + EB_HASH_ALT_CACHE(character_number);
if (cache_p->character_number == character_number) {
memcpy(text, cache_p->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
goto succeeded;
}
/*
* Read the alternation data.
*/
if (zio_lseek(&appendix->subbook_current->zio, location, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
cache_p->character_number = -1;
if (zio_read(&appendix->subbook_current->zio, cache_p->text,
EB_MAX_ALTERNATION_TEXT_LENGTH + 1)
!= EB_MAX_ALTERNATION_TEXT_LENGTH + 1) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
/*
* Update cache data.
*/
memcpy(text, cache_p->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
cache_p->text[EB_MAX_ALTERNATION_TEXT_LENGTH] = '\0';
cache_p->character_number = character_number;
succeeded:
LOG(("out: eb_narrow_alt_character_text_latin(text=%s) = %s",
eb_quoted_string(text), eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*text = '\0';
LOG(("out: eb_narrow_alt_character_text_latin() = %s",
eb_error_string(error_code)));
return error_code;
}
/*
* Return next `n'th character number from `*character_number'.
*/
EB_Error_Code
eb_forward_narrow_alt_character(EB_Appendix *appendix, int n,
int *character_number)
{
EB_Error_Code error_code;
int start;
int end;
int i;
if (n < 0) {
return eb_backward_narrow_alt_character(appendix, -n,
character_number);
}
eb_lock(&appendix->lock);
LOG(("in: eb_forward_narrow_alt_character(appendix=%d, n=%d, \
character_number=%d)",
(int)appendix->code, n, *character_number));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* The narrow font must exist in the current subbook.
*/
if (appendix->subbook_current->narrow_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
start = appendix->subbook_current->narrow_start;
end = appendix->subbook_current->narrow_end;
if (appendix->subbook_current->character_code == EB_CHARCODE_ISO8859_1) {
/*
* Check for `*character_number'. (ISO 8859 1)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x01
|| 0xfe < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (ISO 8859 1)
*/
for (i = 0; i < n; i++) {
if (0xfe <= (*character_number & 0xff))
*character_number += 3;
else
*character_number += 1;
if (end < *character_number) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
} else {
/*
* Check for `*character_number'. (JIS X 0208)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x21
|| 0x7e < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (JIS X 0208)
*/
for (i = 0; i < n; i++) {
if (0x7e <= (*character_number & 0xff))
*character_number += 0xa3;
else
*character_number += 1;
if (end < *character_number) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
}
LOG(("out: eb_forkward_narrow_alt_character(character_number=%d) = %s",
*character_number, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_number = -1;
LOG(("out: eb_forward_narrow_alt_character() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Return previous `n'th character number from `*character_number'.
*/
EB_Error_Code
eb_backward_narrow_alt_character(EB_Appendix *appendix, int n,
int *character_number)
{
EB_Error_Code error_code;
int start;
int end;
int i;
if (n < 0) {
return eb_forward_narrow_alt_character(appendix, -n, character_number);
}
eb_lock(&appendix->lock);
LOG(("in: eb_backward_narrow_alt_character(appendix=%d, n=%d, \
character_number=%d)",
(int)appendix->code, n, *character_number));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* The narrow font must exist in the current subbook.
*/
if (appendix->subbook_current->narrow_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
start = appendix->subbook_current->narrow_start;
end = appendix->subbook_current->narrow_end;
if (appendix->subbook_current->character_code == EB_CHARCODE_ISO8859_1) {
/*
* Check for `*character_number'. (ISO 8859 1)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x01
|| 0xfe < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (ISO 8859 1)
*/
for (i = 0; i < n; i++) {
if ((*character_number & 0xff) <= 0x01)
*character_number -= 3;
else
*character_number -= 1;
if (*character_number < start) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
} else {
/*
* Check for `*character_number'. (JIS X 0208)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x21
|| 0x7e < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (JIS X 0208)
*/
for (i = 0; i < n; i++) {
if ((*character_number & 0xff) <= 0x21)
*character_number -= 0xa3;
else
*character_number -= 1;
if (*character_number < start) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
}
LOG(("out: eb_backward_narrow_alt_character(character_number=%d) = %s",
*character_number, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_number = -1;
LOG(("out: eb_backward_narrow_alt_character() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}

1097
narwfont.c Normal file

File diff suppressed because it is too large Load Diff

2141
readtext.c Normal file

File diff suppressed because it is too large Load Diff

1650
search.c Normal file

File diff suppressed because it is too large Load Diff

1310
setword.c Normal file

File diff suppressed because it is too large Load Diff

111
stopcode.c Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "appendix.h"
#include "text.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `appendix' has a stop-code.
*/
int
eb_have_stop_code(EB_Appendix *appendix)
{
eb_lock(&appendix->lock);
LOG(("in: eb_have_stop_code(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL)
goto failed;
if (appendix->subbook_current->stop_code0 == 0)
goto failed;
LOG(("out: eb_have_stop_code() = %d", 1));
eb_unlock(&appendix->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_stop_code() = %d", 0));
eb_unlock(&appendix->lock);
return 0;
}
/*
* Return the stop-code of the current subbook in `appendix'.
*/
EB_Error_Code
eb_stop_code(EB_Appendix *appendix, int *stop_code)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_stop_code(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
if (appendix->subbook_current->stop_code0 == 0) {
error_code = EB_ERR_NO_STOPCODE;
goto failed;
}
stop_code[0] = appendix->subbook_current->stop_code0;
stop_code[1] = appendix->subbook_current->stop_code1;
LOG(("out: eb_stop_code(stop_code=%d,%d) = %s",
stop_code[0], stop_code[1], eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
stop_code[0] = -1;
stop_code[1] = -1;
LOG(("out: eb_stop_code() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}

105
strcasecmp.c Normal file
View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* This program requires the following Autoconf macros:
*/
#include <sys/types.h>
/*
* Compare strings.
* Cases in the strings are insensitive.
*/
int
eb_strcasecmp(const char *string1, const char *string2)
{
const unsigned char *string1_p = (const unsigned char *)string1;
const unsigned char *string2_p = (const unsigned char *)string2;
int c1, c2;
while (*string1_p != '\0') {
if ('a' <= *string1_p && *string1_p <= 'z')
c1 = *string1_p - ('a' - 'A');
else
c1 = *string1_p;
if ('a' <= *string2_p && *string2_p <= 'z')
c2 = *string2_p - ('a' - 'A');
else
c2 = *string2_p;
if (c1 != c2)
return c1 - c2;
string1_p++;
string2_p++;
}
return -(*string2_p);
}
/*
* Compare strings within `n' characters.
* Cases in the strings are insensitive.
*/
int
eb_strncasecmp(const char *string1, const char *string2, size_t n)
{
const unsigned char *string1_p = (const unsigned char *)string1;
const unsigned char *string2_p = (const unsigned char *)string2;
size_t i = n;
int c1, c2;
if (i <= 0)
return 0;
while (*string1_p != '\0') {
if ('a' <= *string1_p && *string1_p <= 'z')
c1 = *string1_p - ('a' - 'A');
else
c1 = *string1_p;
if ('a' <= *string2_p && *string2_p <= 'z')
c2 = *string2_p - ('a' - 'A');
else
c2 = *string2_p;
if (c1 != c2)
return c1 - c2;
string1_p++;
string2_p++;
i--;
if (i <= 0)
return 0;
}
return -(*string2_p);
}

1140
subbook.c Normal file

File diff suppressed because it is too large Load Diff

121
text.c Normal file
View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' has text body.
* or not.
*/
int
eb_have_text(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_text(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
/*
* Check for the index page of text.
*/
if (book->subbook_current->text.start_page == 0)
goto failed;
LOG(("out: eb_have_text() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_text() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Menu.
*/
EB_Error_Code
eb_text(EB_Book *book, EB_Position *position)
{
EB_Error_Code error_code;
int page;
eb_lock(&book->lock);
LOG(("in: eb_text(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Check for the page number of text.
*/
page = book->subbook_current->text.start_page;
if (page == 0) {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Copy the position to `position'.
*/
position->page = page;
position->offset = 0;
LOG(("out: eb_text(position={%d,%d}) = %s",
position->page, position->offset, eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_text() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

162
text.h Normal file
View File

@ -0,0 +1,162 @@
/* -*- C -*-
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef EB_TEXT_H
#define EB_TEXT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include "defs.h"
/*
* Hook codes.
* (When you add or remove a hook, update EB_NUMER_OF_HOOKS in defs.h.)
*/
#define EB_HOOK_NULL -1
#define EB_HOOK_INITIALIZE 0
#define EB_HOOK_BEGIN_NARROW 1
#define EB_HOOK_END_NARROW 2
#define EB_HOOK_BEGIN_SUBSCRIPT 3
#define EB_HOOK_END_SUBSCRIPT 4
#define EB_HOOK_SET_INDENT 5
#define EB_HOOK_NEWLINE 6
#define EB_HOOK_BEGIN_SUPERSCRIPT 7
#define EB_HOOK_END_SUPERSCRIPT 8
#define EB_HOOK_BEGIN_NO_NEWLINE 9
#define EB_HOOK_END_NO_NEWLINE 10
#define EB_HOOK_BEGIN_EMPHASIS 11
#define EB_HOOK_END_EMPHASIS 12
#define EB_HOOK_BEGIN_CANDIDATE 13
#define EB_HOOK_END_CANDIDATE_GROUP 14
#define EB_HOOK_END_CANDIDATE_LEAF 15
#define EB_HOOK_BEGIN_REFERENCE 16
#define EB_HOOK_END_REFERENCE 17
#define EB_HOOK_BEGIN_KEYWORD 18
#define EB_HOOK_END_KEYWORD 19
#define EB_HOOK_NARROW_FONT 20
#define EB_HOOK_WIDE_FONT 21
#define EB_HOOK_ISO8859_1 22
#define EB_HOOK_NARROW_JISX0208 23
#define EB_HOOK_WIDE_JISX0208 24
#define EB_HOOK_GB2312 25
#define EB_HOOK_BEGIN_MONO_GRAPHIC 26
#define EB_HOOK_END_MONO_GRAPHIC 27
#define EB_HOOK_BEGIN_GRAY_GRAPHIC 28
#define EB_HOOK_END_GRAY_GRAPHIC 29
#define EB_HOOK_BEGIN_COLOR_BMP 30
#define EB_HOOK_BEGIN_COLOR_JPEG 31
#define EB_HOOK_BEGIN_IN_COLOR_BMP 32
#define EB_HOOK_BEGIN_IN_COLOR_JPEG 33
#define EB_HOOK_END_COLOR_GRAPHIC 34
#define EB_HOOK_END_IN_COLOR_GRAPHIC 35
#define EB_HOOK_BEGIN_WAVE 36
#define EB_HOOK_END_WAVE 37
#define EB_HOOK_BEGIN_MPEG 38
#define EB_HOOK_END_MPEG 39
#define EB_HOOK_BEGIN_GRAPHIC_REFERENCE 40
#define EB_HOOK_END_GRAPHIC_REFERENCE 41
#define EB_HOOK_GRAPHIC_REFERENCE 42
#define EB_HOOK_BEGIN_DECORATION 43
#define EB_HOOK_END_DECORATION 44
#define EB_HOOK_BEGIN_IMAGE_PAGE 45
#define EB_HOOK_END_IMAGE_PAGE 46
#define EB_HOOK_BEGIN_CLICKABLE_AREA 47
#define EB_HOOK_END_CLICKABLE_AREA 48
#define EB_HOOK_BEGIN_UNICODE 49
#define EB_HOOK_END_UNICODE 50
#define EB_HOOK_BEGIN_EBXAC_GAIJI 51
#define EB_HOOK_END_EBXAC_GAIJI 52
#define EB_HOOK_EBXAC_GAIJI 53
/*
* Function declarations.
*/
/* hook.c */
void eb_initialize_hookset(EB_Hookset *hookset);
void eb_finalize_hookset(EB_Hookset *hookset);
EB_Error_Code eb_set_hook(EB_Hookset *hookset, const EB_Hook *hook);
EB_Error_Code eb_set_hooks(EB_Hookset *hookset, const EB_Hook *hook);
EB_Error_Code eb_hook_euc_to_ascii(EB_Book *book, EB_Appendix *appendix,
void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv);
EB_Error_Code eb_hook_stop_code(EB_Book *book, EB_Appendix *appendix,
void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv);
EB_Error_Code eb_hook_narrow_character_text(EB_Book *book,
EB_Appendix *appendix, void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv);
EB_Error_Code eb_hook_wide_character_text(EB_Book *book,
EB_Appendix *appendix, void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv);
EB_Error_Code eb_hook_newline(EB_Book *book, EB_Appendix *appendix,
void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv);
EB_Error_Code eb_hook_empty(EB_Book *book, EB_Appendix *appendix,
void *container, EB_Hook_Code hook_code, int argc,
const unsigned int *argv);
/* readtext.c */
EB_Error_Code eb_seek_text(EB_Book *book, const EB_Position *position);
EB_Error_Code eb_tell_text(EB_Book *book, EB_Position *position);
EB_Error_Code eb_read_text(EB_Book *book, EB_Appendix *appendix,
EB_Hookset *hookset, void *container, size_t text_max_length, char *text,
ssize_t *text_length);
EB_Error_Code eb_read_heading(EB_Book *book, EB_Appendix *appendix,
EB_Hookset *hookset, void *container, size_t text_max_length, char *text,
ssize_t *text_length);
EB_Error_Code eb_read_rawtext(EB_Book *book, size_t text_max_length,
char *text, ssize_t *text_length);
int eb_is_text_stopped(EB_Book *book);
EB_Error_Code eb_write_text_byte1(EB_Book *book, int byte1);
EB_Error_Code eb_write_text_byte2(EB_Book *book, int byte1, int byte2);
EB_Error_Code eb_write_text_string(EB_Book *book, const char *string);
EB_Error_Code eb_write_text(EB_Book *book, const char * stream,
size_t stream_length);
const char *eb_current_candidate(EB_Book *book);
EB_Error_Code eb_forward_text(EB_Book *book, EB_Appendix *appendix);
EB_Error_Code eb_backward_text(EB_Book *book, EB_Appendix *appendix);
#ifdef __cplusplus
}
#endif
#endif /* not EB_TEXT_H */

627
widealt.c Normal file
View File

@ -0,0 +1,627 @@
/* automatically generated from narwalt.c. */
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "appendix.h"
#include "build-post.h"
/*
* Unexported functions.
*/
static EB_Error_Code eb_wide_character_text_jis(EB_Appendix *appendix,
int character_number, char *text);
static EB_Error_Code eb_wide_character_text_latin(EB_Appendix *appendix,
int character_number, char *text);
/*
* Hash macro for cache data.
*/
#define EB_HASH_ALT_CACHE(c) ((c) & 0x0f)
/*
* Examine whether the current subbook in `book' has a wide font
* alternation or not.
*/
int
eb_have_wide_alt(EB_Appendix *appendix)
{
eb_lock(&appendix->lock);
LOG(("in: eb_have_wide_alt(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL)
goto failed;
if (appendix->subbook_current->wide_page == 0)
goto failed;
LOG(("out: eb_have_wide_alt() = %d", 1));
eb_unlock(&appendix->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_wide_alt() = %d", 0));
eb_unlock(&appendix->lock);
return 0;
}
/*
* Look up the character number of the start of the wide font alternation
* of the current subbook in `book'.
*/
EB_Error_Code
eb_wide_alt_start(EB_Appendix *appendix, int *start)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_wide_alt_start(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
if (appendix->subbook_current->wide_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
*start = appendix->subbook_current->wide_start;
LOG(("out: eb_wide_alt_start(start=%d) = %s", *start,
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*start = -1;
LOG(("out: eb_wide_alt_start() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Return the character number of the end of the wide font alternation
* of the current subbook in `book'.
*/
EB_Error_Code
eb_wide_alt_end(EB_Appendix *appendix, int *end)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_wide_alt_end(appendix=%d)", (int)appendix->code));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
if (appendix->subbook_current->wide_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
*end = appendix->subbook_current->wide_end;
LOG(("out: eb_wide_alt_end(end=%d) = %s", *end,
eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*end = -1;
LOG(("out: eb_wide_alt_end() = %s", eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the alternation text of the character number `character_number'.
*/
EB_Error_Code
eb_wide_alt_character_text(EB_Appendix *appendix, int character_number,
char *text)
{
EB_Error_Code error_code;
eb_lock(&appendix->lock);
LOG(("in: eb_wide_alt_character_text(appendix=%d, character_number=%d)",
(int)appendix->code, character_number));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* The wide font must exist in the current subbook.
*/
if (appendix->subbook_current->wide_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
if (appendix->subbook_current->character_code == EB_CHARCODE_ISO8859_1) {
error_code = eb_wide_character_text_latin(appendix,
character_number, text);
} else {
error_code = eb_wide_character_text_jis(appendix, character_number,
text);
}
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_wide_alt_character_text(text=%s) = %s",
eb_quoted_string(text), eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*text = '\0';
LOG(("out: eb_wide_alt_character_text() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Get the alternation text of the character number `character_number'.
*/
static EB_Error_Code
eb_wide_character_text_jis(EB_Appendix *appendix, int character_number,
char *text)
{
EB_Error_Code error_code;
int start;
int end;
off_t location;
EB_Alternation_Cache *cachep;
LOG(("in: eb_wide_alt_character_text_jis(appendix=%d, \
character_number=%d)",
(int)appendix->code, character_number));
start = appendix->subbook_current->wide_start;
end = appendix->subbook_current->wide_end;
/*
* Check for `character_number'. Is it in a font?
* This test works correctly even when the font doesn't exist in
* the current subbook because `start' and `end' have set to -1
* in the case.
*/
if (character_number < start
|| end < character_number
|| (character_number & 0xff) < 0x21
|| 0x7e < (character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Calculate the location of alternation data.
*/
location
= (appendix->subbook_current->wide_page - 1) * EB_SIZE_PAGE
+ (((character_number >> 8) - (start >> 8)) * 0x5e
+ (character_number & 0xff) - (start & 0xff))
* (EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
/*
* Check for the cache data.
*/
cachep = appendix->wide_cache + EB_HASH_ALT_CACHE(character_number);
if (cachep->character_number == character_number) {
memcpy(text, cachep->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
goto succeeded;
}
/*
* Read the alternation data.
*/
if (zio_lseek(&appendix->subbook_current->zio, location, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
cachep->character_number = -1;
if (zio_read(&appendix->subbook_current->zio, cachep->text,
EB_MAX_ALTERNATION_TEXT_LENGTH + 1)
!= EB_MAX_ALTERNATION_TEXT_LENGTH + 1) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
/*
* Update cache data.
*/
memcpy(text, cachep->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
cachep->text[EB_MAX_ALTERNATION_TEXT_LENGTH] = '\0';
cachep->character_number = character_number;
succeeded:
LOG(("out: eb_wide_alt_character_text_jis(text=%s) = %s",
eb_quoted_string(text), eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*text = '\0';
LOG(("out: eb_wide_alt_character_text_jis() = %s",
eb_error_string(error_code)));
return error_code;
}
/*
* Get the alternation text of the character number `character_number'.
*/
static EB_Error_Code
eb_wide_character_text_latin(EB_Appendix *appendix, int character_number,
char *text)
{
EB_Error_Code error_code;
int start;
int end;
off_t location;
EB_Alternation_Cache *cache_p;
LOG(("in: eb_wide_alt_character_text_latin(appendix=%d, \
character_number=%d)",
(int)appendix->code, character_number));
start = appendix->subbook_current->wide_start;
end = appendix->subbook_current->wide_end;
/*
* Check for `character_number'. Is it in a font?
* This test works correctly even when the font doesn't exist in
* the current subbook because `start' and `end' have set to -1
* in the case.
*/
if (character_number < start
|| end < character_number
|| (character_number & 0xff) < 0x01
|| 0xfe < (character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Calculate the location of alternation data.
*/
location
= (appendix->subbook_current->wide_page - 1) * EB_SIZE_PAGE
+ (((character_number >> 8) - (start >> 8)) * 0xfe
+ (character_number & 0xff) - (start & 0xff))
* (EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
/*
* Check for the cache data.
*/
cache_p = appendix->wide_cache + EB_HASH_ALT_CACHE(character_number);
if (cache_p->character_number == character_number) {
memcpy(text, cache_p->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
goto succeeded;
}
/*
* Read the alternation data.
*/
if (zio_lseek(&appendix->subbook_current->zio, location, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_APP;
goto failed;
}
cache_p->character_number = -1;
if (zio_read(&appendix->subbook_current->zio, cache_p->text,
EB_MAX_ALTERNATION_TEXT_LENGTH + 1)
!= EB_MAX_ALTERNATION_TEXT_LENGTH + 1) {
error_code = EB_ERR_FAIL_READ_APP;
goto failed;
}
/*
* Update cache data.
*/
memcpy(text, cache_p->text, EB_MAX_ALTERNATION_TEXT_LENGTH + 1);
cache_p->text[EB_MAX_ALTERNATION_TEXT_LENGTH] = '\0';
cache_p->character_number = character_number;
succeeded:
LOG(("out: eb_wide_alt_character_text_latin(text=%s) = %s",
eb_quoted_string(text), eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*text = '\0';
LOG(("out: eb_wide_alt_character_text_latin() = %s",
eb_error_string(error_code)));
return error_code;
}
/*
* Return next `n'th character number from `*character_number'.
*/
EB_Error_Code
eb_forward_wide_alt_character(EB_Appendix *appendix, int n,
int *character_number)
{
EB_Error_Code error_code;
int start;
int end;
int i;
if (n < 0) {
return eb_backward_wide_alt_character(appendix, -n,
character_number);
}
eb_lock(&appendix->lock);
LOG(("in: eb_forward_wide_alt_character(appendix=%d, n=%d, \
character_number=%d)",
(int)appendix->code, n, *character_number));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* The wide font must exist in the current subbook.
*/
if (appendix->subbook_current->wide_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
start = appendix->subbook_current->wide_start;
end = appendix->subbook_current->wide_end;
if (appendix->subbook_current->character_code == EB_CHARCODE_ISO8859_1) {
/*
* Check for `*character_number'. (ISO 8859 1)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x01
|| 0xfe < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (ISO 8859 1)
*/
for (i = 0; i < n; i++) {
if (0xfe <= (*character_number & 0xff))
*character_number += 3;
else
*character_number += 1;
if (end < *character_number) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
} else {
/*
* Check for `*character_number'. (JIS X 0208)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x21
|| 0x7e < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (JIS X 0208)
*/
for (i = 0; i < n; i++) {
if (0x7e <= (*character_number & 0xff))
*character_number += 0xa3;
else
*character_number += 1;
if (end < *character_number) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
}
LOG(("out: eb_forkward_wide_alt_character(character_number=%d) = %s",
*character_number, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_number = -1;
LOG(("out: eb_forward_wide_alt_character() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}
/*
* Return previous `n'th character number from `*character_number'.
*/
EB_Error_Code
eb_backward_wide_alt_character(EB_Appendix *appendix, int n,
int *character_number)
{
EB_Error_Code error_code;
int start;
int end;
int i;
if (n < 0) {
return eb_forward_wide_alt_character(appendix, -n, character_number);
}
eb_lock(&appendix->lock);
LOG(("in: eb_backward_wide_alt_character(appendix=%d, n=%d, \
character_number=%d)",
(int)appendix->code, n, *character_number));
/*
* Current subbook must have been set.
*/
if (appendix->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_APPSUB;
goto failed;
}
/*
* The wide font must exist in the current subbook.
*/
if (appendix->subbook_current->wide_page == 0) {
error_code = EB_ERR_NO_ALT;
goto failed;
}
start = appendix->subbook_current->wide_start;
end = appendix->subbook_current->wide_end;
if (appendix->subbook_current->character_code == EB_CHARCODE_ISO8859_1) {
/*
* Check for `*character_number'. (ISO 8859 1)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x01
|| 0xfe < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (ISO 8859 1)
*/
for (i = 0; i < n; i++) {
if ((*character_number & 0xff) <= 0x01)
*character_number -= 3;
else
*character_number -= 1;
if (*character_number < start) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
} else {
/*
* Check for `*character_number'. (JIS X 0208)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x21
|| 0x7e < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
/*
* Get character number. (JIS X 0208)
*/
for (i = 0; i < n; i++) {
if ((*character_number & 0xff) <= 0x21)
*character_number -= 0xa3;
else
*character_number -= 1;
if (*character_number < start) {
error_code = EB_ERR_NO_SUCH_CHAR_TEXT;
goto failed;
}
}
}
LOG(("out: eb_backward_wide_alt_character(character_number=%d) = %s",
*character_number, eb_error_string(EB_SUCCESS)));
eb_unlock(&appendix->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_number = -1;
LOG(("out: eb_backward_wide_alt_character() = %s",
eb_error_string(error_code)));
eb_unlock(&appendix->lock);
return error_code;
}

1098
widefont.c Normal file

File diff suppressed because it is too large Load Diff

185
word.c Normal file
View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "build-post.h"
/*
* Examine whether the current subbook in `book' supports `WORD SEARCH'
* or not.
*/
int
eb_have_word_search(EB_Book *book)
{
eb_lock(&book->lock);
LOG(("in: eb_have_word_search(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
goto failed;
if (book->subbook_current->word_alphabet.start_page == 0
&& book->subbook_current->word_asis.start_page == 0
&& book->subbook_current->word_kana.start_page == 0)
goto failed;
LOG(("out: eb_have_word_search() = %d", 1));
eb_unlock(&book->lock);
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_word_search() = %d", 0));
eb_unlock(&book->lock);
return 0;
}
/*
* Word search.
*/
EB_Error_Code
eb_search_word(EB_Book *book, const char *input_word)
{
EB_Error_Code error_code;
EB_Word_Code word_code;
EB_Search_Context *context;
eb_lock(&book->lock);
LOG(("in: eb_search_word(book=%d, input_word=%s)", (int)book->code,
eb_quoted_string(input_word)));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
}
/*
* Initialize search context.
*/
eb_reset_search_contexts(book);
context = book->search_contexts;
context->code = EB_SEARCH_WORD;
/*
* Make a fixed word and a canonicalized word to search from
* `input_word'.
*/
error_code = eb_set_word(book, input_word, context->word,
context->canonicalized_word, &word_code);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Get a page number.
*/
switch (word_code) {
case EB_WORD_ALPHABET:
if (book->subbook_current->word_alphabet.start_page != 0)
context->page = book->subbook_current->word_alphabet.start_page;
else if (book->subbook_current->word_asis.start_page != 0)
context->page = book->subbook_current->word_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
case EB_WORD_KANA:
if (book->subbook_current->word_kana.start_page != 0)
context->page = book->subbook_current->word_kana.start_page;
else if (book->subbook_current->word_asis.start_page != 0)
context->page = book->subbook_current->word_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
case EB_WORD_OTHER:
if (book->subbook_current->word_asis.start_page != 0)
context->page = book->subbook_current->word_asis.start_page;
else {
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
break;
default:
error_code = EB_ERR_NO_SUCH_SEARCH;
goto failed;
}
/*
* Choose comparison functions.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word;
} else if (context->page == book->subbook_current->word_kana.start_page) {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word_kana_single;
context->compare_group = eb_match_word_kana_group;
} else {
context->compare_pre = eb_pre_match_word;
context->compare_single = eb_match_word;
context->compare_group = eb_match_word_kana_group;
}
/*
* Pre-search.
*/
error_code = eb_presearch_word(book, context);
if (error_code != EB_SUCCESS)
goto failed;
LOG(("out: eb_search_word() = %s", eb_error_string(EB_SUCCESS)));
eb_unlock(&book->lock);
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_reset_search_contexts(book);
LOG(("out: eb_search_word() = %s", eb_error_string(error_code)));
eb_unlock(&book->lock);
return error_code;
}

3
zig.go
View File

@ -10,8 +10,7 @@ import (
)
/*
#cgo LDFLAGS: -L"./eb/eb/.libs" -l:libeb.a -lz
#cgo CFLAGS: -I"./eb/"
#cgo LDFLAGS: -lz
#include "zig.h"
*/
import "C"

8
zig.h
View File

@ -1,8 +1,8 @@
#include <stdlib.h>
#include <eb/eb.h>
#include <eb/font.h>
#include <eb/text.h>
#include <eb/error.h>
#include "eb.h"
#include "font.h"
#include "text.h"
#include "error.h"
extern EB_Error_Code installHook(EB_Hookset* hookset, EB_Hook_Code code);

2014
zio.c Normal file

File diff suppressed because it is too large Load Diff

232
zio.h Normal file
View File

@ -0,0 +1,232 @@
/* -*- C -*-
* Copyright (c) 2001-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef ZIO_H
#define ZIO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <time.h>
/*
* Header size of the ebzip compression file.
*/
#define ZIO_SIZE_EBZIP_HEADER 22
/*
* Margin size for ebzip compression buffer.
* (Since compressed data is larger than original in the worst case,
* we must add margin to a compression buffer.)
*/
#define ZIO_SIZE_EBZIP_MARGIN 1024
/*
* Maximum ebzio compression level.
*/
#define ZIO_MAX_EBZIP_LEVEL 5
/*
* Huffman node types.
*/
#define ZIO_HUFFMAN_NODE_INTERMEDIATE 0
#define ZIO_HUFFMAN_NODE_EOF 1
#define ZIO_HUFFMAN_NODE_LEAF8 2
#define ZIO_HUFFMAN_NODE_LEAF16 3
#define ZIO_HUFFMAN_NODE_LEAF32 4
/*
* Compression type codes.
*/
#define ZIO_PLAIN 0
#define ZIO_EBZIP1 1
#define ZIO_EPWING 2
#define ZIO_EPWING6 3
#define ZIO_SEBXA 4
#define ZIO_INVALID -1
#define ZIO_REOPEN -2
/*
* Compression type.
*/
typedef int Zio_Code;
/*
* A node of static Huffman tree.
*/
typedef struct Zio_Huffman_Node_Struct Zio_Huffman_Node;
struct Zio_Huffman_Node_Struct {
/*
* node type (ITNERMEDIATE, LEAF8, LEAF16, LEAF32 or EOF).
*/
int type;
/*
* Value of a leaf node.
*/
unsigned int value;
/*
* Frequency of a node.
*/
int frequency;
/*
* Left child.
*/
Zio_Huffman_Node *left;
/*
* Right child.
*/
Zio_Huffman_Node *right;
};
/*
* Compression information of a book.
*/
typedef struct Zio_Struct Zio;
struct Zio_Struct {
/*
* ID.
*/
int id;
/*
* Zio type. (PLAIN, EBZIP, EPWING, EPWING6 or SEBXA)
*/
Zio_Code code;
/*
* File descriptor.
*/
int file;
/*
* Current location.
*/
off_t location;
/*
* Size of an uncompressed file.
*/
off_t file_size;
/*
* Slice size of an EBZIP compressed file.
*/
size_t slice_size;
/*
* Compression level. (EBZIP compression only)
*/
int zip_level;
/*
* Length of an index. (EBZIP compression only)
*/
int index_width;
/*
* Adler-32 check sum of an uncompressed file. (EBZIP compression only)
*/
unsigned int crc;
/*
* mtime of an uncompressed file. (EBZIP compression only)
*/
time_t mtime;
/*
* Location of an index table. (EPWING and S-EBXA compression only)
*/
off_t index_location;
/*
* Length of an index table. (EPWING and S-EBXA compression only)
*/
size_t index_length;
/*
* Location of a frequency table. (EPWING compression only)
*/
off_t frequencies_location;
/*
* Length of a frequency table. (EPWING compression only)
*/
size_t frequencies_length;
/*
* Huffman tree nodes. (EPWING compression only)
*/
Zio_Huffman_Node *huffman_nodes;
/*
* Root node of a Huffman tree. (EPWING compression only)
*/
Zio_Huffman_Node *huffman_root;
/*
* Region of compressed pages. (S-EBXA compression only)
*/
off_t zio_start_location;
off_t zio_end_location;
/*
* Add this value to offset written in index. (S-EBXA compression only)
*/
off_t index_base;
};
/*
* Function declarations.
*/
/* zio.c */
int zio_initialize_library(void);
void zio_finalize_library(void);
void zio_initialize(Zio *zio);
void zio_finalize(Zio *zio);
int zio_set_sebxa_mode(Zio *zio, off_t index_location, off_t index_base,
off_t zio_start_location, off_t zio_end_location);
int zio_open(Zio *zio, const char *file_name, Zio_Code zio_code);
void zio_close(Zio *zio);
int zio_file(Zio *zio);
Zio_Code zio_mode(Zio *zio);
off_t zio_lseek(Zio *zio, off_t offset, int whence);
ssize_t zio_read(Zio *zio, char *buffer, size_t length);
#ifdef __cplusplus
}
#endif
#endif /* not ZIO_H */