summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2005-07-08 14:45:55 +0000
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2005-07-08 14:45:55 +0000
commitfdfe5b42f687fbf3d4537541cc1b0bd9b8c2c090 (patch)
tree81d199b6fbbb11d3f310668e5bdabf9129e5f41f
parent232dbc756390d30a86ae6de0cc84600eddb1c0b2 (diff)
downloadlibrcc-fdfe5b42f687fbf3d4537541cc1b0bd9b8c2c090.tar.gz
librcc-fdfe5b42f687fbf3d4537541cc1b0bd9b8c2c090.tar.bz2
librcc-fdfe5b42f687fbf3d4537541cc1b0bd9b8c2c090.tar.xz
librcc-fdfe5b42f687fbf3d4537541cc1b0bd9b8c2c090.zip
08.07.2005
-rw-r--r--Makefile.am3
-rwxr-xr-xautogen.sh76
-rw-r--r--configure.in114
-rw-r--r--m4/ax_compare_version.m4153
-rw-r--r--m4/ax_path_bdb.m4575
-rw-r--r--src/Makefile.am6
-rw-r--r--src/db4.c0
-rw-r--r--src/db4.h5
-rw-r--r--src/engine.c93
-rw-r--r--src/engine.h28
-rw-r--r--src/fake_rcd.h22
-rw-r--r--src/fs.c3
-rw-r--r--src/internal.h5
-rw-r--r--src/librcc.c46
-rw-r--r--src/librcc.h15
-rw-r--r--src/lng.c29
-rw-r--r--src/lng.h6
-rw-r--r--src/lngconfig.c80
-rw-r--r--src/lngconfig.h5
-rw-r--r--src/opt.h19
-rw-r--r--src/plugin.c1
-rw-r--r--src/rccconfig.c20
-rw-r--r--src/rccdb4.c124
-rw-r--r--src/rccdb4.h23
-rw-r--r--src/rccenca.c24
-rw-r--r--src/rccxml.c97
-rw-r--r--src/recode.c16
-rw-r--r--ui/gtk.c6
-rw-r--r--ui/librccui.c9
-rw-r--r--ui/rccnames.c2
30 files changed, 1465 insertions, 140 deletions
diff --git a/Makefile.am b/Makefile.am
index 618d546..90d0a74 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,4 @@
SUBDIRS = src ui
+EXTRA_DIST = librcd.spec
-EXTRA_DIST = librcd.spec \ No newline at end of file
+ACLOCAL_AMFLAGS = -I m4
diff --git a/autogen.sh b/autogen.sh
index 917a587..2aa7001 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,9 +1,71 @@
-#!/bin/bash
+#!/bin/sh
+PROG=`basename $0`
+
+KEYFILE=src/librcc.c
+
+# Some OS's have multiple versions (autoconf259, etc.) and don't have an
+# autoconf binary
+
+AUTOCONF=`which autoconf`
+if test x"${AUTOCONF}" != x -a -f ${AUTOCONF}
+then
+ AUTOCONF=autoconf
+ AUTOMAKE=automake
+ ACLOCAL=aclocal
+ LIBTOOLIZE=libtoolize
+ AUTOHEADER=autoheader
+else
+ FINDPATH=`echo ${PATH}|sed -e 's,:, ,g'`
+ AUTOCONF=`find ${FINDPATH} -name "autoconf*"|sort -r|head -1`
+ AUTOMAKE=`find ${FINDPATH} -name "automake*"|sort -r|head -1`
+ ACLOCAL=`find ${FINDPATH} -name "aclocal*"|sort -r|head -1`
+ LIBTOOLIZE=`find ${FINDPATH} -name "libtoolize*"|sort -r|head -1`
+ AUTOHEADER=`find /usr/bin /usr/local/bin -name "autoheader*"|sort -r|head -1`
+ echo "$0: autoconf: using ${AUTOCONF}"
+ echo "$0: automake: using ${AUTOMAKE}"
+ echo "$0: aclocal: using ${ACLOCAL}"
+ echo "$0: libtoolize: using ${LIBTOOLIZE}"
+ echo "$0: autoheader: using ${AUTOHEADER}"
+fi
+
+GETTEXTIZE_FLAGS=--no-changelog
+AUTOPOINT_FLAGS=
+LIBTOOLIZE_FLAGS=
+
+# Some OS's require /usr/local/share/aclocal
+
+if test ! -d /usr/local/share/aclocal
+then
+ ACLOCAL_FLAGS='-I m4'
+else
+ ACLOCAL_FLAGS='-I m4 -I /usr/local/share/aclocal'
+fi
+AUTOHEADER_FLAGS=-Wall
+AUTOMAKE_FLAGS='--add-missing -Wall'
+AUTOCONF_FLAGS=-Wno-obsolete
+
+die()
+{
+ err=$?
+ echo "$PROG: exited by previous error(s), return code was $err" >&2
+ exit 1
+}
+
+if [ ! -f $KEYFILE ]
+then
+ echo "$PROG: key-file \`$KEYFILE' not found, exiting." >&2
+ echo "$PROG: hint: you should run $PROG from top-level sourse directory." >&2
+ exit 1
+fi
+
+# gettextize ${GETTEXTIZE_FLAGS}
+# autopoint ${AUTOPOINT_FLAGS}
+# xml-i18n-toolize || die
+# intltoolize || die
+${LIBTOOLIZE} ${LIBTOOLIZE_FLAGS} --force || die
+${ACLOCAL} ${ACLOCAL_FLAGS} || die
+${AUTOHEADER} ${AUTOHEADER_FLAGS} || die
+${AUTOMAKE} ${AUTOMAKE_FLAGS} || die
+${AUTOCONF} ${AUTOCONF_FLAGS} || die
-rm -f configure
-aclocal
-autoheader
-libtoolize --force
-automake
-autoconf \ No newline at end of file
diff --git a/configure.in b/configure.in
index e2fe1c4..7d50ab6 100644
--- a/configure.in
+++ b/configure.in
@@ -29,6 +29,10 @@ AC_SUBST(LIBRCC_CVS_DATE)
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
+AC_ARG_ENABLE( force-dynamic-engines,
+ [ --enable-force-dynamic-engines force usage of dynamic engines],,
+ enable_force_dynamic_engines="no")
+
AC_PROG_CC
AC_PROG_INSTALL
AM_PROG_LIBTOOL
@@ -41,7 +45,7 @@ dnl Checks for programs.
dnl Checks for header files.
AC_CHECK_HEADERS(iconv.h,, [AC_MSG_ERROR(Missing iconv header)])
-AC_CHECK_HEADERS(mntent.h pwd.h sys/types.h unistd.h)
+AC_CHECK_HEADERS(mntent.h pwd.h sys/types.h sys/stat.h unistd.h)
AC_TRY_COMPILE([#include <langinfo.h>],
[char *codeset = nl_langinfo (CODESET);],
@@ -61,37 +65,97 @@ AC_SUBST(XML_INCLUDES)
AC_PATH_PROG(GTK_CONFIG, gtk-config, no)
AM_CONDITIONAL(HAVE_GTK, [ test $GTK_CONFIG != no ])
-GTK_LIBS="\`gtk-config --libs\`"
-GTK_INCLUDES="\`gtk-config --cflags\`"
+if test $GTK_CONFIG = no; then
+ GTK_LIBS=""
+ GTK_INCLUDES=""
+ HAVE_GTK=no
+else
+ GTK_LIBS="\`gtk-config --libs\`"
+ GTK_INCLUDES="\`gtk-config --cflags\`"
+ HAVE_GTK=yes
+fi
AC_SUBST(GTK_LIBS)
AC_SUBST(GTK_INCLUDES)
+AC_CHECK_HEADER(dlfcn.h, [AC_CHECK_LIB(dl, dlopen, [
+ AC_DEFINE(HAVE_DLOPEN,1,[Defines if dlopen is available])
+ DLOPEN_LIBS="-ldl"
+ DLOPEN_INCLUDES=""
+ HAVE_DLOPEN=yes
+],[
+ DLOPEN_LIBS=""
+ DLOPEN_INCLUDES=""
+ HAVE_DLOPEN=no
+])])
+
+if test $enable_force_dynamic_engines = yes; then
+ RCD_LIBS=""
+ RCD_INCLUDES=""
+ HAVE_RCD=no
+ ENCA_LIBS=""
+ ENCA_INCLUDES=""
+ HAVE_ENCA=no
+else
AC_CHECK_HEADER(librcd.h, [AC_CHECK_LIB(rcd, rcdGetRussianCharset, [
+ AC_DEFINE(HAVE_RCD,1,[Defines if libRCD is available])
RCD_LIBS="-lrcd"
RCD_INCLUDES=""
-], AC_MSG_ERROR(LibRCD is required))], [AC_MSG_ERROR(LibRCD is required)])
-AC_SUBST(RCD_LIBS)
-AC_SUBST(RCD_INCLUDES)
-
-AC_CHECK_HEADER(enca.h, [AC_CHECK_LIB(enca, enca_analyse, [
- AC_DEFINE(HAVE_ENCA,1,[Defines if enca is available])
- ENCA_LIBS="-lenca"
- ENCA_INCLUDES=""
+ HAVE_RCD=yes
+],[
+ RCD_LIBS=""
+ RCD_INCLUDES=""
+ HAVE_RCD=no
])])
-
-if test "x$ENCA_LIBS" = "x"; then
- AC_CHECK_HEADER(dlfcn.h, [AC_CHECK_LIB(dl, dlopen, [
- AC_DEFINE(HAVE_DLOPEN,1,[Defines if dlopen is available])
- ENCA_LIBS="-ldl"
+AC_CHECK_HEADER(enca.h, [AC_CHECK_LIB(enca, enca_analyse, [
+ AC_DEFINE(HAVE_ENCA,1,[Defines if enca is available])
+ ENCA_LIBS="-lenca"
ENCA_INCLUDES=""
- ],[
+ HAVE_ENCA=yes
+],[
ENCA_LIBS=""
ENCA_INCLUDES=""
- ])])
+ HAVE_ENCA=no
+])])
fi
+
+AC_SUBST(RCD_LIBS)
+AC_SUBST(RCD_INCLUDES)
AC_SUBST(ENCA_LIBS)
AC_SUBST(ENCA_INCLUDES)
+USE_DLOPEN=no
+if test $HAVE_DLOPEN = yes; then
+ if test $HAVE_ENCA = no; then
+ HAVE_ENCA=dynamic
+ USE_DLOPEN=yes
+ fi
+ if test $HAVE_RCD = no; then
+ HAVE_RCD=dynamic
+ USE_DLOPEN=yes
+ fi
+
+ if test $USE_DLOPEN = no; then
+ DLOPEN_LIBS=""
+ DLOPEN_INCLUDES=""
+ fi
+fi
+AC_SUBST(DLOPEN_LIBS)
+AC_SUBST(DLOPEN_INCLUDES)
+
+
+AX_PATH_BDB([4],[
+ BDB_LIBS="$BDB_LDFLAGS $BDB_LIBS"
+ BDB_INCLUDES="$BDB_CPPFLAGS"
+ HAVE_BDB=yes
+],[
+ BDB_LIBS=""
+ BDB_INCLUDES=""
+ HAVE_BDB=no
+])
+AC_SUBST(BDB_LIBS)
+AC_SUBST(BDB_INCLUDES)
+
+
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -99,3 +163,17 @@ dnl Checks for library functions.
AC_CHECK_FUNCS(strcasecmp strncasecmp strdup)
AC_OUTPUT(src/Makefile ui/Makefile examples/Makefile Makefile librcc.spec)
+
+echo ""
+echo "Configuration:"
+echo " Dynamic Engine Loading Support: $HAVE_DLOPEN"
+echo " Enca Charset Detection Support: $HAVE_ENCA"
+echo " LibRCD Charset Detection Support: $HAVE_RCD"
+echo ""
+echo " Multilanguage support with DB4: $HAVE_BDB"
+echo ""
+echo "User Interfaces:"
+echo " GTK User Interface: $HAVE_GTK"
+echo ""
+echo ""
+echo ""
diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4
new file mode 100644
index 0000000..7a54a73
--- /dev/null
+++ b/m4/ax_compare_version.m4
@@ -0,0 +1,153 @@
+dnl @synopsis AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+dnl
+dnl This macro compares two version strings. It is used heavily in the
+dnl macro _AX_PATH_BDB for library checking. Due to the various number
+dnl of minor-version numbers that can exist, and the fact that string
+dnl comparisons are not compatible with numeric comparisons, this is
+dnl not necessarily trivial to do in a autoconf script. This macro makes
+dnl doing these comparisons easy.
+dnl
+dnl The six basic comparisons are available, as well as checking
+dnl equality limited to a certain number of minor-version levels.
+dnl
+dnl The operator OP determines what type of comparison to do, and
+dnl can be one of:
+dnl eq - equal (test A == B)
+dnl ne - not equal (test A != B)
+dnl le - less than or equal (test A <= B)
+dnl ge - greater than or equal (test A >= B)
+dnl lt - less than (test A < B)
+dnl gt - greater than (test A > B)
+dnl
+dnl Additionally, the eq and ne operator can have a number after it
+dnl to limit the test to that number of minor versions.
+dnl eq0 - equal up to the length of the shorter version
+dnl ne0 - not equal up to the length of the shorter version
+dnl eqN - equal up to N sub-version levels
+dnl neN - not equal up to N sub-version levels
+dnl
+dnl When the condition is true, shell commands ACTION-IF-TRUE are run,
+dnl otherwise shell commands ACTION-IF-FALSE are run. The environment
+dnl variable 'ax_compare_version' is always set to either 'true' or 'false'
+dnl as well.
+dnl
+dnl Examples:
+dnl AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+dnl AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+dnl would both be true.
+dnl
+dnl AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+dnl AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+dnl would both be false.
+dnl
+dnl AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+dnl would be true because it is only comparing two minor versions.
+dnl AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+dnl would be true because it is only comparing the lesser number of
+dnl minor versions of the two values.
+dnl
+dnl Note: The characters that separate the version numbers do not
+dnl matter. An empty string is the same as version 0. OP is evaluated
+dnl by autoconf, not configure, so must be a string, not a variable.
+dnl
+dnl The author would like to acknowledge Guido Draheim whose advice about
+dnl the m4_case and m4_ifvaln functions make this macro only include
+dnl the portions necessary to perform the specific comparison specified
+dnl by the OP argument in the final configure script.
+dnl
+dnl @version $Id: ax_compare_version.m4,v 1.1 2004/03/01 19:14:43 guidod Exp $
+dnl @author Tim Toolan <toolan@ele.uri.edu>
+dnl
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+ AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+ A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+ B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+ dnl # then the first line is used to determine if the condition is true.
+ dnl # The sed right after the echo is to remove any indented white space.
+ m4_case(m4_tolower($2),
+ [lt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [gt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [le],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],
+ [ge],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],[
+ dnl Split the operator from the subversion count if present.
+ m4_bmatch(m4_substr($2,2),
+ [0],[
+ # A count of zero means use the length of the shorter version.
+ # Determine the number of characters in A and B.
+ ax_compare_version_len_A=`echo "$A" | awk '{print(length)}'`
+ ax_compare_version_len_B=`echo "$B" | awk '{print(length)}'`
+
+ # Set A to no more than B's length and B to no more than A's length.
+ A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+ ],
+ [[0-9]+],[
+ # A count greater than zero means use only that many subversions
+ A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ ],
+ [.+],[
+ AC_WARNING(
+ [illegal OP numeric parameter: $2])
+ ],[])
+
+ # Pad zeros at end of numbers to make same length.
+ ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+ B="$B`echo $A | sed 's/./0/g'`"
+ A="$ax_compare_version_tmp_A"
+
+ # Check for equality or inequality as necessary.
+ m4_case(m4_tolower(m4_substr($2,0,2)),
+ [eq],[
+ test "x$A" = "x$B" && ax_compare_version=true
+ ],
+ [ne],[
+ test "x$A" != "x$B" && ax_compare_version=true
+ ],[
+ AC_WARNING([illegal OP parameter: $2])
+ ])
+ ])
+
+ AS_VAR_POPDEF([A])dnl
+ AS_VAR_POPDEF([B])dnl
+
+ dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+ if test "$ax_compare_version" = "true" ; then
+ m4_ifvaln([$4],[$4],[:])dnl
+ m4_ifvaln([$5],[else $5])dnl
+ fi
+]) dnl AX_COMPARE_VERSION
diff --git a/m4/ax_path_bdb.m4 b/m4/ax_path_bdb.m4
new file mode 100644
index 0000000..cb4eb12
--- /dev/null
+++ b/m4/ax_path_bdb.m4
@@ -0,0 +1,575 @@
+dnl @synopsis AX_PATH_BDB([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl
+dnl This macro finds the latest version of Berkeley DB on the system,
+dnl and ensures that the header file and library versions match. If
+dnl MINIMUM-VERSION is specified, it will ensure that the library
+dnl found is at least that version.
+dnl
+dnl It determines the name of the library as well as the path to the
+dnl header file and library. It will check both the default environment
+dnl as well as the default Berkeley DB install location. When found, it
+dnl sets BDB_LIBS, BDB_CPPFLAGS, and BDB_LDFLAGS to the necessary values
+dnl to add to LIBS, CPPFLAGS, and LDFLAGS, as well as setting BDB_VERSION
+dnl to the version found. HAVE_DB_H is defined also.
+dnl
+dnl The option --with-bdb-dir=DIR can be used to specify a specific
+dnl Berkeley DB installation to use.
+dnl
+dnl An example of it's use is:
+dnl AX_PATH_BDB([3],[
+dnl LIBS="$BDB_LIBS $LIBS"
+dnl LDFLAGS="$BDB_LDFLAGS $LDFLAGS"
+dnl CPPFLAGS="$CPPFLAGS $BDB_CPPFLAGS"
+dnl ])
+dnl which will locate the latest version of Berkeley DB on the system,
+dnl and ensure that it is version 3.0 or higher.
+dnl
+dnl Details: This macro does not use either AC_CHECK_HEADERS or
+dnl AC_CHECK_LIB because, first, the functions inside the library are
+dnl sometimes renamed to contain a version code that is only available
+dnl from the db.h on the system, and second, because it is common to
+dnl have multiple db.h and libdb files on a system it is important to
+dnl make sure the ones being used correspond to the same version.
+dnl Additionally, there are many different possible names for libdb
+dnl when installed by an OS distribution, and these need to be checked
+dnl if db.h does not correspond to libdb.
+dnl
+dnl When cross compiling, only header versions are verified since it
+dnl would be difficult to check the library version. Additionally
+dnl the default Berkeley DB installation locations /usr/local/BerkeleyDB*
+dnl are not searched for higher versions of the library.
+dnl
+dnl The format for the list of library names to search came from the
+dnl Cyrus IMAP distribution, although they are generated dynamically
+dnl here, and only for the version found in db.h.
+dnl
+dnl The macro AX_COMPARE_VERSION is required to use this macro, and
+dnl should be available from the Autoconf Macro Archive.
+dnl
+dnl The author would like to acknowledge the generous and valuable feedback
+dnl from Guido Draheim, without which this macro would be far less robust,
+dnl and have poor and inconsistent cross compilation support.
+dnl
+dnl Changes:
+dnl 1/5/05 applied patch from Rafa Rzepecki to eliminate compiler
+dnl warning about unused variable, argv
+dnl
+dnl @version $Id: ax_path_bdb.m4,v 1.3 2005/01/20 00:15:41 guidod Exp $
+dnl @author Tim Toolan <toolan@ele.uri.edu>
+dnl
+
+dnl #########################################################################
+AC_DEFUN([AX_PATH_BDB], [
+ dnl # Used to indicate success or failure of this function.
+ ax_path_bdb_ok=no
+
+ # Add --with-bdb-dir option to configure.
+ AC_ARG_WITH([bdb-dir],
+ [AC_HELP_STRING([--with-bdb-dir=DIR],
+ [Berkeley DB installation directory])])
+
+ # Check if --with-bdb-dir was specified.
+ if test "x$with_bdb_dir" = "x" ; then
+ # No option specified, so just search the system.
+ AX_PATH_BDB_NO_OPTIONS([$1], [HIGHEST], [
+ ax_path_bdb_ok=yes
+ ])
+ else
+ # Set --with-bdb-dir option.
+ ax_path_bdb_INC="$with_bdb_dir/include"
+ ax_path_bdb_LIB="$with_bdb_dir/lib"
+
+ dnl # Save previous environment, and modify with new stuff.
+ ax_path_bdb_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="-I$ax_path_bdb_INC $CPPFLAGS"
+
+ ax_path_bdb_save_LDFLAGS=$LDFLAGS
+ LDFLAGS="-L$ax_path_bdb_LIB $LDFLAGS"
+
+ # Check for specific header file db.h
+ AC_MSG_CHECKING([db.h presence in $ax_path_bdb_INC])
+ if test -f "$ax_path_bdb_INC/db.h" ; then
+ AC_MSG_RESULT([yes])
+ # Check for library
+ AX_PATH_BDB_NO_OPTIONS([$1], [ENVONLY], [
+ ax_path_bdb_ok=yes
+ BDB_CPPFLAGS="-I$ax_path_bdb_INC"
+ BDB_LDFLAGS="-L$ax_path_bdb_LIB"
+ ])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_NOTICE([no usable Berkeley DB not found])
+ fi
+
+ dnl # Restore the environment.
+ CPPFLAGS="$ax_path_bdb_save_CPPFLAGS"
+ LDFLAGS="$ax_path_bdb_save_LDFLAGS"
+
+ fi
+
+ dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+ if test "$ax_path_bdb_ok" = "yes" ; then
+ m4_ifvaln([$2],[$2],[:])dnl
+ m4_ifvaln([$3],[else $3])dnl
+ fi
+
+]) dnl AX_PATH_BDB
+
+dnl #########################################################################
+dnl Check for berkeley DB of at least MINIMUM-VERSION on system.
+dnl
+dnl The OPTION argument determines how the checks occur, and can be one of:
+dnl
+dnl HIGHEST - Check both the environment and the default installation
+dnl directories for Berkeley DB and choose the version that
+dnl is highest. (default)
+dnl ENVFIRST - Check the environment first, and if no satisfactory
+dnl library is found there check the default installation
+dnl directories for Berkeley DB which is /usr/local/BerkeleyDB*
+dnl ENVONLY - Check the current environment only.
+dnl
+dnl Requires AX_PATH_BDB_PATH_GET_VERSION, AX_PATH_BDB_PATH_FIND_HIGHEST,
+dnl AX_PATH_BDB_ENV_CONFIRM_LIB, AX_PATH_BDB_ENV_GET_VERSION, and
+dnl AX_COMPARE_VERSION macros.
+dnl
+dnl Result: sets ax_path_bdb_no_options_ok to yes or no
+dnl sets BDB_LIBS, BDB_CPPFLAGS, BDB_LDFLAGS, BDB_VERSION
+dnl
+dnl AX_PATH_BDB_NO_OPTIONS([MINIMUM-VERSION], [OPTION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_NO_OPTIONS], [
+ dnl # Used to indicate success or failure of this function.
+ ax_path_bdb_no_options_ok=no
+
+ # Values to add to environment to use Berkeley DB.
+ BDB_VERSION=''
+ BDB_LIBS=''
+ BDB_CPPFLAGS=''
+ BDB_LDFLAGS=''
+
+ # Check cross compilation here.
+ if test "x$cross_compiling" = "xyes" ; then
+ # If cross compiling, can't use AC_RUN_IFELSE so do these tests.
+ # The AC_PREPROC_IFELSE confirms that db.h is preprocessable,
+ # and extracts the version number from it.
+ AC_MSG_CHECKING([for db.h])
+
+ AS_VAR_PUSHDEF([HEADER_VERSION],[ax_path_bdb_no_options_HEADER_VERSION])dnl
+ HEADER_VERSION=''
+ AC_PREPROC_IFELSE([
+ AC_LANG_SOURCE([[
+#include <db.h>
+AX_PATH_BDB_STUFF DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH
+ ]])
+ ],[
+ # Extract version from preprocessor output.
+ HEADER_VERSION=`eval "$ac_cpp conftest.$ac_ext" 2> /dev/null \
+ | grep AX_PATH_BDB_STUFF | sed 's/[[^0-9,]]//g;s/,/./g;1q'`
+ ],[])
+
+ if test "x$HEADER_VERSION" = "x" ; then
+ AC_MSG_RESULT([no])
+ else
+ AC_MSG_RESULT([$HEADER_VERSION])
+
+ # Check that version is high enough.
+ AX_COMPARE_VERSION([$HEADER_VERSION],[ge],[$1],[
+ # get major and minor version numbers
+ AS_VAR_PUSHDEF([MAJ],[ax_path_bdb_no_options_MAJOR])dnl
+ MAJ=`echo $HEADER_VERSION | sed 's,\..*,,'`
+ AS_VAR_PUSHDEF([MIN],[ax_path_bdb_no_options_MINOR])dnl
+ MIN=`echo $HEADER_VERSION | sed 's,^[[0-9]]*\.,,;s,\.[[0-9]]*$,,'`
+
+ dnl # Save LIBS.
+ ax_path_bdb_no_options_save_LIBS="$LIBS"
+
+ # Check that we can link with the library.
+ AC_SEARCH_LIBS([db_version],
+ [db db-$MAJ.$MIN db$MAJ.$MIN db$MAJ$MIN db-$MAJ db$MAJ],[
+ # Sucessfully found library.
+ ax_path_bdb_no_options_ok=yes
+ BDB_VERSION=$HEADER_VERSION
+
+ # Extract library from LIBS
+ ax_path_bdb_no_options_LEN=` \
+ echo "x$ax_path_bdb_no_options_save_LIBS" \
+ | awk '{print(length)}'`
+ BDB_LIBS=`echo "x$LIBS " \
+ | sed "s/.\{$ax_path_bdb_no_options_LEN\}\$//;s/^x//;s/ //g"`
+ ],[])
+
+ dnl # Restore LIBS
+ LIBS="$ax_path_bdb_no_options_save_LIBS"
+
+ AS_VAR_POPDEF([MAJ])dnl
+ AS_VAR_POPDEF([MIN])dnl
+ ])
+ fi
+
+ AS_VAR_POPDEF([HEADER_VERSION])dnl
+ else
+ # Not cross compiling.
+ # Check version of Berkeley DB in the current environment.
+ AX_PATH_BDB_ENV_GET_VERSION([
+ AX_COMPARE_VERSION([$ax_path_bdb_env_get_version_VERSION],[ge],[$1],[
+ # Found acceptable version in current environment.
+ ax_path_bdb_no_options_ok=yes
+ BDB_VERSION="$ax_path_bdb_env_get_version_VERSION"
+ BDB_LIBS="$ax_path_bdb_env_get_version_LIBS"
+ ])
+ ])
+
+ # Determine if we need to search /usr/local/BerkeleyDB*
+ ax_path_bdb_no_options_DONE=no
+ if test "x$2" = "xENVONLY" ; then
+ ax_path_bdb_no_options_DONE=yes
+ elif test "x$2" = "xENVFIRST" ; then
+ ax_path_bdb_no_options_DONE=$ax_path_bdb_no_options_ok
+ fi
+
+ if test "$ax_path_bdb_no_options_DONE" = "no" ; then
+ # Check for highest in /usr/local/BerkeleyDB*
+ AX_PATH_BDB_PATH_FIND_HIGHEST([
+ if test "$ax_path_bdb_no_options_ok" = "yes" ; then
+ # If we already have an acceptable version use this if higher.
+ AX_COMPARE_VERSION(
+ [$ax_path_bdb_path_find_highest_VERSION],[gt],[$BDB_VERSION])
+ else
+ # Since we didn't have an acceptable version check if this one is.
+ AX_COMPARE_VERSION(
+ [$ax_path_bdb_path_find_highest_VERSION],[ge],[$1])
+ fi
+ ])
+
+ dnl # If result from _AX_COMPARE_VERSION is true we want this version.
+ if test "$ax_compare_version" = "true" ; then
+ ax_path_bdb_no_options_ok=yes
+ BDB_LIBS="-ldb"
+ if test "x$ax_path_bdb_path_find_highest_DIR" != x ; then
+ BDB_CPPFLAGS="-I$ax_path_bdb_path_find_highest_DIR/include"
+ BDB_LDFLAGS="-L$ax_path_bdb_path_find_highest_DIR/lib"
+ fi
+ BDB_VERSION="$ax_path_bdb_path_find_highest_VERSION"
+ fi
+ fi
+ fi
+
+ dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+ if test "$ax_path_bdb_no_options_ok" = "yes" ; then
+ AC_MSG_NOTICE([using Berkeley DB version $BDB_VERSION])
+ AC_DEFINE([HAVE_DB_H],[1],
+ [Define to 1 if you have the <db.h> header file.])
+ m4_ifvaln([$3],[$3])dnl
+ else
+ AC_MSG_NOTICE([no Berkeley DB version $1 or higher found])
+ m4_ifvaln([$4],[$4])dnl
+ fi
+]) dnl AX_PATH_BDB_NO_OPTIONS
+
+dnl #########################################################################
+dnl Check the default installation directory for Berkeley DB which is
+dnl of the form /usr/local/BerkeleyDB* for the highest version.
+dnl
+dnl Result: sets ax_path_bdb_path_find_highest_ok to yes or no,
+dnl sets ax_path_bdb_path_find_highest_VERSION to version,
+dnl sets ax_path_bdb_path_find_highest_DIR to directory.
+dnl
+dnl AX_PATH_BDB_PATH_FIND_HIGHEST([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_PATH_FIND_HIGHEST], [
+ dnl # Used to indicate success or failure of this function.
+ ax_path_bdb_path_find_highest_ok=no
+
+ AS_VAR_PUSHDEF([VERSION],[ax_path_bdb_path_find_highest_VERSION])dnl
+ VERSION=''
+
+ ax_path_bdb_path_find_highest_DIR=''
+
+ # find highest verison in default install directory for Berkeley DB
+ AS_VAR_PUSHDEF([CURDIR],[ax_path_bdb_path_find_highest_CURDIR])dnl
+ AS_VAR_PUSHDEF([CUR_VERSION],[ax_path_bdb_path_get_version_VERSION])dnl
+
+ for CURDIR in `ls -d /usr/local/BerkeleyDB* 2> /dev/null`
+ do
+ AX_PATH_BDB_PATH_GET_VERSION([$CURDIR],[
+ AX_COMPARE_VERSION([$CUR_VERSION],[gt],[$VERSION],[
+ ax_path_bdb_path_find_highest_ok=yes
+ ax_path_bdb_path_find_highest_DIR="$CURDIR"
+ VERSION="$CUR_VERSION"
+ ])
+ ])
+ done
+
+ AS_VAR_POPDEF([VERSION])dnl
+ AS_VAR_POPDEF([CUR_VERSION])dnl
+ AS_VAR_POPDEF([CURDIR])dnl
+
+ dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+ if test "$ax_path_bdb_path_find_highest_ok" = "yes" ; then
+ m4_ifvaln([$1],[$1],[:])dnl
+ m4_ifvaln([$2],[else $2])dnl
+ fi
+
+]) dnl AX_PATH_BDB_PATH_FIND_HIGHEST
+
+dnl #########################################################################
+dnl Checks for Berkeley DB in specified directory's lib and include
+dnl subdirectories.
+dnl
+dnl Result: sets ax_path_bdb_path_get_version_ok to yes or no,
+dnl sets ax_path_bdb_path_get_version_VERSION to version.
+dnl
+dnl AX_PATH_BDB_PATH_GET_VERSION(BDB-DIR, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_PATH_GET_VERSION], [
+ dnl # Used to indicate success or failure of this function.
+ ax_path_bdb_path_get_version_ok=no
+
+ # Indicate status of checking for Berkeley DB header.
+ AC_MSG_CHECKING([in $1/include for db.h])
+ ax_path_bdb_path_get_version_got_header=no
+ test -f "$1/include/db.h" && ax_path_bdb_path_get_version_got_header=yes
+ AC_MSG_RESULT([$ax_path_bdb_path_get_version_got_header])
+
+ # Indicate status of checking for Berkeley DB library.
+ AC_MSG_CHECKING([in $1/lib for library -ldb])
+
+ ax_path_bdb_path_get_version_VERSION=''
+
+ if test -d "$1/include" && test -d "$1/lib" &&
+ test "$ax_path_bdb_path_get_version_got_header" = "yes" ; then
+ dnl # save and modify environment
+ ax_path_bdb_path_get_version_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="-I$1/include $CPPFLAGS"
+
+ ax_path_bdb_path_get_version_save_LIBS="$LIBS"
+ LIBS="$LIBS -ldb"
+
+ ax_path_bdb_path_get_version_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="-L$1/lib $LDFLAGS"
+
+ # Compile and run a program that compares the version defined in
+ # the header file with a version defined in the library function
+ # db_version.
+ AC_RUN_IFELSE([
+ AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <db.h>
+int main(int argc,char **argv)
+{
+ int major,minor,patch;
+ (void) argv;
+ db_version(&major,&minor,&patch);
+ if (argc > 1)
+ printf("%d.%d.%d\n",DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH);
+ if (DB_VERSION_MAJOR == major && DB_VERSION_MINOR == minor &&
+ DB_VERSION_PATCH == patch)
+ return 0;
+ else
+ return 1;
+}
+ ]])
+ ],[
+ # Program compiled and ran, so get version by adding argument.
+ ax_path_bdb_path_get_version_VERSION=`./conftest$ac_exeext x`
+ ax_path_bdb_path_get_version_ok=yes
+ ],[],[])
+
+ dnl # restore environment
+ CPPFLAGS="$ax_path_bdb_path_get_version_save_CPPFLAGS"
+ LIBS="$ax_path_bdb_path_get_version_save_LIBS"
+ LDFLAGS="$ax_path_bdb_path_get_version_save_LDFLAGS"
+ fi
+
+ dnl # Finally, execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+ if test "$ax_path_bdb_path_get_version_ok" = "yes" ; then
+ AC_MSG_RESULT([$ax_path_bdb_path_get_version_VERSION])
+ m4_ifvaln([$2],[$2])dnl
+ else
+ AC_MSG_RESULT([no])
+ m4_ifvaln([$3],[$3])dnl
+ fi
+]) dnl AX_PATH_BDB_PATH_GET_VERSION
+
+#############################################################################
+dnl Checks if version of library and header match specified version.
+dnl Only meant to be used by AX_PATH_BDB_ENV_GET_VERSION macro.
+dnl
+dnl Requires AX_COMPARE_VERSION macro.
+dnl
+dnl Result: sets ax_path_bdb_env_confirm_lib_ok to yes or no.
+dnl
+dnl AX_PATH_BDB_ENV_CONFIRM_LIB(VERSION, [LIBNAME])
+AC_DEFUN([AX_PATH_BDB_ENV_CONFIRM_LIB], [
+ dnl # Used to indicate success or failure of this function.
+ ax_path_bdb_env_confirm_lib_ok=no
+
+ dnl # save and modify environment to link with library LIBNAME
+ ax_path_bdb_env_confirm_lib_save_LIBS="$LIBS"
+ LIBS="$LIBS $2"
+
+ # Compile and run a program that compares the version defined in
+ # the header file with a version defined in the library function
+ # db_version.
+ AC_RUN_IFELSE([
+ AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <db.h>
+int main(int argc,char **argv)
+{
+ int major,minor,patch;
+ (void) argv;
+ db_version(&major,&minor,&patch);
+ if (argc > 1)
+ printf("%d.%d.%d\n",DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH);
+ if (DB_VERSION_MAJOR == major && DB_VERSION_MINOR == minor &&
+ DB_VERSION_PATCH == patch)
+ return 0;
+ else
+ return 1;
+}
+ ]])
+ ],[
+ # Program compiled and ran, so get version by giving an argument,
+ # which will tell the program to print the output.
+ ax_path_bdb_env_confirm_lib_VERSION=`./conftest$ac_exeext x`
+
+ # If the versions all match up, indicate success.
+ AX_COMPARE_VERSION([$ax_path_bdb_env_confirm_lib_VERSION],[eq],[$1],[
+ ax_path_bdb_env_confirm_lib_ok=yes
+ ])
+ ],[],[])
+
+ dnl # restore environment
+ LIBS="$ax_path_bdb_env_confirm_lib_save_LIBS"
+
+]) dnl AX_PATH_BDB_ENV_CONFIRM_LIB
+
+#############################################################################
+dnl Finds the version and library name for Berkeley DB in the
+dnl current environment. Tries many different names for library.
+dnl
+dnl Requires AX_PATH_BDB_ENV_CONFIRM_LIB macro.
+dnl
+dnl Result: set ax_path_bdb_env_get_version_ok to yes or no,
+dnl set ax_path_bdb_env_get_version_VERSION to the version found,
+dnl and ax_path_bdb_env_get_version_LIBNAME to the library name.
+dnl
+dnl AX_PATH_BDB_ENV_GET_VERSION([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_ENV_GET_VERSION], [
+ dnl # Used to indicate success or failure of this function.
+ ax_path_bdb_env_get_version_ok=no
+
+ ax_path_bdb_env_get_version_VERSION=''
+ ax_path_bdb_env_get_version_LIBS=''
+
+ AS_VAR_PUSHDEF([HEADER_VERSION],[ax_path_bdb_env_get_version_HEADER_VERSION])dnl
+ AS_VAR_PUSHDEF([TEST_LIBNAME],[ax_path_bdb_env_get_version_TEST_LIBNAME])dnl
+
+ # Indicate status of checking for Berkeley DB library.
+ AC_MSG_CHECKING([for db.h])
+
+ # Compile and run a program that determines the Berkeley DB version
+ # in the header file db.h.
+ HEADER_VERSION=''
+ AC_RUN_IFELSE([
+ AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <db.h>
+int main(int argc,char **argv)
+{
+ (void) argv;
+ if (argc > 1)
+ printf("%d.%d.%d\n",DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH);
+ return 0;
+}
+ ]])
+ ],[
+ # Program compiled and ran, so get version by adding an argument.
+ HEADER_VERSION=`./conftest$ac_exeext x`
+ AC_MSG_RESULT([$HEADER_VERSION])
+ ],[AC_MSG_RESULT([no])],[AC_MSG_RESULT([no])])
+
+ # Have header version, so try to find corresponding library.
+ # Looks for library names in the order:
+ # nothing, db, db-X.Y, dbX.Y, dbXY, db-X, dbX
+ # and stops when it finds the first one that matches the version
+ # of the header file.
+ if test "x$HEADER_VERSION" != "x" ; then
+ AC_MSG_CHECKING([for library containing Berkeley DB $HEADER_VERSION])
+
+ AS_VAR_PUSHDEF([MAJOR],[ax_path_bdb_env_get_version_MAJOR])dnl
+ AS_VAR_PUSHDEF([MINOR],[ax_path_bdb_env_get_version_MINOR])dnl
+
+ # get major and minor version numbers
+ MAJOR=`echo $HEADER_VERSION | sed 's,\..*,,'`
+ MINOR=`echo $HEADER_VERSION | sed 's,^[[0-9]]*\.,,;s,\.[[0-9]]*$,,'`
+
+ # see if it is already specified in LIBS
+ TEST_LIBNAME=''
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+ # try format "db"
+ TEST_LIBNAME='-ldb'
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+ fi
+
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+ # try format "db-X.Y"
+ TEST_LIBNAME="-ldb-${MAJOR}.$MINOR"
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+ fi
+
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+ # try format "dbX.Y"
+ TEST_LIBNAME="-ldb${MAJOR}.$MINOR"
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+ fi
+
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+ # try format "dbXY"
+ TEST_LIBNAME="-ldb$MAJOR$MINOR"
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+ fi
+
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+ # try format "db-X"
+ TEST_LIBNAME="-ldb-$MAJOR"
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+ fi
+
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+ # try format "dbX"
+ TEST_LIBNAME="-ldb$MAJOR"
+ AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+ fi
+
+ dnl # Found a valid library.
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "yes" ; then
+ if test "x$TEST_LIBNAME" = "x" ; then
+ AC_MSG_RESULT([none required])
+ else
+ AC_MSG_RESULT([$TEST_LIBNAME])
+ fi
+ ax_path_bdb_env_get_version_VERSION="$HEADER_VERSION"
+ ax_path_bdb_env_get_version_LIBS="$TEST_LIBNAME"
+ ax_path_bdb_env_get_version_ok=yes
+ else
+ AC_MSG_RESULT([no])
+ fi
+
+ AS_VAR_POPDEF([MAJOR])dnl
+ AS_VAR_POPDEF([MINOR])dnl
+ fi
+
+ AS_VAR_POPDEF([HEADER_VERSION])dnl
+ AS_VAR_POPDEF([TEST_LIBNAME])dnl
+
+ dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+ if test "$ax_path_bdb_env_confirm_lib_ok" = "yes" ; then
+ m4_ifvaln([$1],[$1],[:])dnl
+ m4_ifvaln([$2],[else $2])dnl
+ fi
+
+]) dnl BDB_ENV_GET_VERSION
+
+#############################################################################
+
diff --git a/src/Makefile.am b/src/Makefile.am
index bef8240..022ef1b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,9 @@ librcc_la_SOURCES = librcc.c \
rccconfig.c rccconfig.h \
rcclist.c rcclist.h \
plugin.c plugin.h \
+ fake_enca.h fake_rcd.h \
rccenca.c rccenca.h \
+ rccdb4.c rccdb4.h \
engine.c engine.h \
rccstring.c rccstring.h \
rccxml.c rccxml.h \
@@ -18,7 +20,7 @@ librcc_la_SOURCES = librcc.c \
internal.h
include_HEADERS = librcc.h
-INCLUDES = @XML_INCLUDES@ @RCD_INCLUDES@ @ENCA_INCLUDES@
-librcc_la_LIBADD = @XML_LIBS@ @RCD_LIBS@ @ENCA_LIBS@
+INCLUDES = @XML_INCLUDES@ @DLOPEN_INCLUDES@ @RCD_INCLUDES@ @ENCA_INCLUDES@ @BDB_INCLUDES@
+librcc_la_LIBADD = @XML_LIBS@ @DLOPEN_LIBS@ @RCD_LIBS@ @ENCA_LIBS@ @BDB_LIBS@
librcc_la_LDFLAGS = -version-info @LIBRCC_VERSION_INFO@
diff --git a/src/db4.c b/src/db4.c
deleted file mode 100644
index e69de29..0000000
--- a/src/db4.c
+++ /dev/null
diff --git a/src/db4.h b/src/db4.h
deleted file mode 100644
index e13dd5f..0000000
--- a/src/db4.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef _RCC_DB4_H
-#define _RCC_DB4_H
-
-
-#endif /* _RCC_DB4_H */
diff --git a/src/engine.c b/src/engine.c
index 5f7a3ff..5bb8b7a 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2,8 +2,95 @@
#include <string.h>
#include "internal.h"
+#include "plugin.h"
+#include "rccconfig.h"
-int rccEngineInit(rcc_engine_context engine_ctx, rcc_context ctx) {
+#include "engine.h"
+
+#ifdef RCC_RCD_SUPPORT
+# ifdef RCC_RCD_DYNAMIC
+# include "fake_rcd.h"
+# else
+# include <librcd.h>
+# endif /* RCC_RCD_DYNAMIC */
+#endif /* RCC_RCD_SUPPORT */
+
+static rcc_library_handle rcd_handle = NULL;
+
+rcc_charset_id rccAutoengineRussian(rcc_engine_context ctx, const char *buf, int len) {
+#ifdef RCC_RCD_SUPPORT
+ rcc_charset_id id;
+# ifdef RCC_RCD_DYNAMIC
+ if (!rcdGetRussianCharset) return (rcc_charset_id)-1;
+# endif /* RCC_RCD_DYNAMIC */
+ return (rcc_charset_id)rcdGetRussianCharset(buf,len);
+#else /* RCC_RCD_SUPPORT */
+ return (rcc_charset_id)-1;
+#endif /* RCC_RCD_SUPPORT */
+}
+
+
+static int rccRCDLibraryLoad() {
+#ifdef RCC_RCD_DYNAMIC
+ if (rcd_handle) return 0;
+
+ rcd_handle = rccLibraryOpen(RCC_RCD_LIB);
+ if (!rcd_handle) return -1;
+
+ rcdGetRussianCharset = rccLibraryFind(rcd_handle,"rcdGetRussianCharset");
+ if (!rcdGetRussianCharset) {
+ rccLibraryClose(rcd_handle);
+ rcd_handle = NULL;
+# ifdef RCC_DEBUG
+ perror( "rccRCD. Incomplete function set in library" );
+# endif /* RCC_DEBUG */
+ return -1;
+ }
+#endif /* RCC_RCD_DYNAMIC */
+
+ return 0;
+}
+
+static void rccRCDLibraryUnload() {
+#ifdef RCC_RCD_DYNAMIC
+ if (rcd_handle) {
+ rccLibraryClose(rcd_handle);
+ rcd_handle = NULL;
+ }
+#endif /* RCC_RCD_DYNAMIC */
+}
+
+int rccEngineInit() {
+#ifdef RCC_RCD_DYNAMIC
+ int err;
+ unsigned int i,j,flag;
+ rcc_engine **engines;
+ int *charsets;
+
+ err = rccRCDLibraryLoad();
+ if (err) {
+ for (i=0;rcc_default_languages[i].sn;i++) {
+ engines = rcc_default_languages[i].engines;
+ for (flag=0,j=0;engines[j];j++) {
+ if (flag) engines[j-1] = engines[j];
+ else if (engines[j] == &rcc_russian_engine) flag=1;
+ }
+ if (flag) engines[j-1] = NULL;
+ }
+ }
+#endif /* RCC_RCD_DYNAMIC */
+
+ return rccEncaInit();
+}
+
+void rccEngineFree() {
+ rccEncaFree();
+#ifdef RCC_RCD_DYNAMIC
+ rccRCDLibraryUnload();
+#endif /* RCC_RCD_DYNAMIC */
+}
+
+int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_context ctx) {
if ((!ctx)||(!engine_ctx)) return -1;
engine_ctx->ctx = ctx;
@@ -12,7 +99,7 @@ int rccEngineInit(rcc_engine_context engine_ctx, rcc_context ctx) {
return 0;
}
-void rccEngineFree(rcc_engine_context engine_ctx) {
+void rccEngineFreeContext(rcc_engine_context engine_ctx) {
if (!engine_ctx) return;
if (engine_ctx->free_func) {
@@ -31,7 +118,7 @@ int rccEngineConfigure(rcc_engine_context ctx) {
if ((!ctx)||(!ctx->ctx)) return -1;
- rccEngineFree(ctx);
+ rccEngineFreeContext(ctx);
language_id = rccGetCurrentLanguage(ctx->ctx);
if (language_id == (rcc_language_id)-1) return -1;
diff --git a/src/engine.h b/src/engine.h
index c0cb57d..0d16d9f 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -1,6 +1,25 @@
#ifndef _RCC_ENGINE_H
#define _RCC_ENGINE_H
+#include "../config.h"
+
+#ifdef HAVE_RCD
+# define RCC_RCD_SUPPORT
+# undef RCC_RCD_DYNAMIC
+#elif HAVE_DLOPEN
+# define RCC_RCD_SUPPORT
+# define RCC_RCD_DYNAMIC
+#else
+# undef RCC_RCD_SUPPORT
+# undef RCC_RCD_DYNAMIC
+#endif
+
+#define RCC_RCD_LIB "librcd.so.0"
+
+#ifdef RCC_RCD_DYNAMIC
+# define RCC_RCD_SUPPORT
+#endif
+
struct rcc_engine_context_t {
rcc_context ctx;
rcc_language *language;
@@ -12,9 +31,14 @@ struct rcc_engine_context_t {
};
typedef struct rcc_engine_context_t rcc_engine_context_s;
-int rccEngineInit(rcc_engine_context engine_ctx, rcc_context ctx);
-void rccEngineFree(rcc_engine_context engine_ctx);
+int rccEngineInit();
+void rccEngineFree();
+
+int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_context ctx);
+void rccEngineFreeContext(rcc_engine_context engine_ctx);
rcc_engine_internal rccEngineGetInternal(rcc_engine_context ctx);
+rcc_charset_id rccAutoengineRussian(rcc_engine_context ctx, const char *buf, int len);
+
#endif /* _RCC_ENGINE_H */
diff --git a/src/fake_rcd.h b/src/fake_rcd.h
new file mode 100644
index 0000000..8dcb9ae
--- /dev/null
+++ b/src/fake_rcd.h
@@ -0,0 +1,22 @@
+#ifndef _LIBRCD_H
+#define _LIBRCD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum rcd_russian_charset_t {
+ RUSSIAN_CHARSET_WIN = 0,
+ RUSSIAN_CHARSET_KOI,
+ RUSSIAN_CHARSET_UTF8,
+ RUSSIAN_CHARSET_ALT
+};
+typedef enum rcd_russian_charset_t rcd_russian_charset;
+
+rcd_russian_charset (*rcdGetRussianCharset)(const char *buf, int len) = NULL;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBRCD_H */
diff --git a/src/fs.c b/src/fs.c
index 9c79dc4..2906850 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -174,15 +174,12 @@ const char *rccFS2(rcc_context ctx, iconv_t icnv, const char *prefix, const char
if (icnv == (iconv_t)-1) return NULL;
if (icnv == (iconv_t)-2) {
- puts("-1");
strncpy(ctx->tmpbuffer, name, RCC_MAX_STRING_CHARS);
ctx->tmpbuffer[RCC_MAX_STRING_CHARS] = 0;
} else {
- puts("-2");
err = rccIConv(ctx, icnv, name, 0);
if (err<=0) return NULL;
}
- puts("ok");
return rccCheckFile(prefix, ctx->tmpbuffer);
}
diff --git a/src/internal.h b/src/internal.h
index ac9a74e..8a99ca0 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -7,6 +7,7 @@
#include "engine.h"
#include "lngconfig.h"
#include "rccstring.h"
+#include "rccdb4.h"
#define STRNLEN(str,n) (n?strnlen(str,n):strlen(str))
@@ -44,6 +45,8 @@ struct rcc_context_t {
rcc_language_config current_config;
rcc_language_id current_language;
+ db4_context db4ctx;
+
unsigned int configuration_lock;
};
typedef struct rcc_context_t rcc_context_s;
@@ -52,4 +55,6 @@ int rccConfigure(rcc_context ctx);
char *rccCreateResult(rcc_context ctx, size_t len, size_t *rlen);
extern rcc_context rcc_default_ctx;
+extern char *rcc_home_dir;
+
#endif /* _RCC_INTERNAL_H */
diff --git a/src/librcc.c b/src/librcc.c
index d29ba8b..2e2a49e 100644
--- a/src/librcc.c
+++ b/src/librcc.c
@@ -16,13 +16,11 @@
# include <pwd.h>
#endif /* HAVE_PWD_H */
-#include <librcd.h>
-
#include "internal.h"
#include "rccconfig.h"
#include "rccenca.h"
#include "rcclist.h"
-#include "rccenca.h"
+#include "engine.h"
#include "rccxml.h"
static int initialized = 0;
@@ -51,8 +49,7 @@ int rccInit() {
#endif /* HAVE_PWD_H */
if (!rcc_home_dir) rcc_home_dir = strdup("/");
-
- err = rccEncaInit();
+ err = rccEngineInit();
if (!err) err = rccXmlInit();
if (err) {
@@ -72,7 +69,7 @@ void rccFree() {
}
rccXmlFree();
- rccEncaFree();
+ rccEngineFree();
if (rcc_home_dir) {
free(rcc_home_dir);
@@ -126,6 +123,8 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
}
ctx->configuration_lock = 0;
+
+ ctx->db4ctx = NULL;
ctx->aliases[0] = NULL;
for (i=0;rcc_default_aliases[i].alias;i++)
@@ -158,7 +157,7 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
for (i=0;i<max_languages;i++)
configs[i].charset = NULL;
- err = rccEngineInit(&ctx->engine_ctx, ctx);
+ err = rccEngineInitContext(&ctx->engine_ctx, ctx);
if (err) {
rccFree(ctx);
return NULL;
@@ -175,6 +174,8 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
} else {
strcpy(ctx->locale_variable, RCC_LOCALE_VARIABLE);
}
+
+ for (i=0;i<RCC_MAX_OPTIONS;i++) rccOptionSetDefault(ctx, (rcc_option)i);
if (flags&RCC_NO_DEFAULT_CONFIGURATION) {
rccRegisterLanguage(ctx, rcc_default_languages);
@@ -201,11 +202,6 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
}
}
- for (i=0;i<RCC_MAX_OPTIONS;i++) {
- ctx->options[i] = rccGetOptionDefaultValue((rcc_option)i);
- ctx->default_options[i] = 1;
- }
-
ctx->configure = 1;
return ctx;
@@ -251,7 +247,8 @@ void rccFreeContext(rcc_context ctx) {
unsigned int i;
if (ctx) {
- rccEngineFree(&ctx->engine_ctx);
+ if (ctx->db4ctx) rccDb4FreeContext(ctx->db4ctx);
+ rccEngineFreeContext(&ctx->engine_ctx);
rccFreeIConv(ctx);
if (ctx->iconv_from) free(ctx->iconv_from);
if (ctx->iconv_to) free(ctx->iconv_to);
@@ -380,14 +377,19 @@ int rccConfigure(rcc_context ctx) {
unsigned int i;
rcc_charset *charsets;
const char *charset;
+ rcc_language_config cfg;
if (!ctx) return -1;
if (!ctx->configure) return 0;
- rccGetCurrentCharsetName(ctx, (rcc_class_id)0);
+ cfg = rccGetCurrentConfig(ctx);
+ if (!cfg) return 1;
+
+ rccConfigGetCurrentCharsetName(cfg, (rcc_class_id)0);
rccFreeIConv(ctx);
for (i=0;i<ctx->n_classes;i++) {
- charset = rccGetCurrentCharsetName(ctx, (rcc_class_id)i);
+ charset = rccConfigGetCurrentCharsetName(cfg, (rcc_class_id)i);
+ if (!charset) continue;
printf("Configure %i: %s\n", i, charset);
if (strcmp(charset, "UTF-8")&&strcmp(charset, "UTF8")) {
ctx->iconv_from[i] = iconv_open("UTF-8", charset);
@@ -399,12 +401,14 @@ int rccConfigure(rcc_context ctx) {
}
charsets = rccGetCurrentAutoCharsetList(ctx);
- for (i=0;charsets[i];i++) {
- charset = charsets[i];
- if (strcmp(charset, "UTF-8")&&strcmp(charset, "UTF8"))
- ctx->iconv_auto[i] = iconv_open("UTF-8", charset);
- else
- ctx->iconv_auto[i] = (iconv_t)-2;
+ if (charsets) {
+ for (i=0;charsets[i];i++) {
+ charset = charsets[i];
+ if (strcmp(charset, "UTF-8")&&strcmp(charset, "UTF8"))
+ ctx->iconv_auto[i] = iconv_open("UTF-8", charset);
+ else
+ ctx->iconv_auto[i] = (iconv_t)-2;
+ }
}
err = rccEngineConfigure(&ctx->engine_ctx);
diff --git a/src/librcc.h b/src/librcc.h
index 79aab7e..e6fe7bc 100644
--- a/src/librcc.h
+++ b/src/librcc.h
@@ -48,6 +48,9 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
int rccInitDefaultContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags);
void rccFreeContext(rcc_context ctx);
+typedef unsigned int rcc_db4_flags;
+int rccInitDb4(rcc_context ctx, const char *name, rcc_db4_flags flags);
+
int rccLockConfiguration(rcc_context ctx, unsigned int lock_code);
int rccUnlockConfiguration(rcc_context ctx, unsigned int lock_code);
@@ -114,10 +117,17 @@ typedef enum rcc_class_type_t {
RCC_CLASS_FS
} rcc_class_type;
+struct rcc_class_default_charset_t {
+ const char *lang;
+ const char *charset;
+};
+typedef const struct rcc_class_default_charset_t rcc_class_default_charset;
+
struct rcc_class_t {
const char *name;
- const char *defvalue; /* locale variable name or parrent name */
const rcc_class_type class_type;
+ const char *defvalue; /* locale variable name or parrent name */
+ rcc_class_default_charset *defcharset;
const char *fullname;
};
typedef const struct rcc_class_t rcc_class;
@@ -134,6 +144,7 @@ typedef enum rcc_option_t {
RCC_LEARNING_MODE = 0,
RCC_AUTODETECT_FS_TITLES,
RCC_AUTODETECT_FS_NAMES,
+ RCC_CONFIGURED_LANGUAGES_ONLY,
RCC_MAX_OPTIONS
} rcc_option;
@@ -141,7 +152,7 @@ struct rcc_option_name_t {
rcc_option option;
const char *name;
- const char *sn;
+ const char **subnames;
};
typedef struct rcc_option_name_t rcc_option_name;
diff --git a/src/lng.c b/src/lng.c
index e69b946..e6b5a73 100644
--- a/src/lng.c
+++ b/src/lng.c
@@ -29,9 +29,9 @@ rcc_language_id rccGetLanguageByName(rcc_context ctx, const char *name) {
else return (rcc_language_id)-1;
}
if (!name) return (rcc_language_id)-1;
-
- for (i=0;ctx->languages[i];i++)
- if (!strcmp(ctx->languages[i]->sn, name)) return i;
+
+ for (i=0;ctx->languages[i];i++)
+ if (!strcasecmp(ctx->languages[i]->sn, name)) return (rcc_language_id)i;
return (rcc_language_id)-1;
}
@@ -41,16 +41,18 @@ static rcc_language_id rccGetDefaultLanguage(rcc_context ctx) {
unsigned int i;
char stmp[RCC_MAX_LANGUAGE_CHARS+1];
- err = rccLocaleGetLanguage(stmp, ctx->locale_variable, RCC_MAX_LANGUAGE_CHARS);
- if (err) {
- if (ctx->n_languages>1) return (rcc_language_id)1;
- return (rcc_language_id)-1;
+ if (!rccLocaleGetLanguage(stmp, ctx->locale_variable, RCC_MAX_LANGUAGE_CHARS)) {
+ for (i=0;ctx->languages[i];i++) {
+ if (!strcmp(ctx->languages[i]->sn, stmp)) {
+ if (rccGetOption(ctx, RCC_CONFIGURED_LANGUAGES_ONLY)) {
+ if (!rccCheckConfig(ctx, (rcc_language_id)i)) break;
+ }
+ return (rcc_language_id)i;
+ }
+ }
}
- for (i=0;ctx->languages[i];i++)
- if (!strcmp(ctx->languages[i]->sn, stmp)) return (rcc_language_id)i;
-
- if (i>1) return (rcc_language_id)1;
+ if (ctx->n_languages>1) return (rcc_language_id)1;
return (rcc_language_id)-1;
}
@@ -116,17 +118,20 @@ int rccSetLanguage(rcc_context ctx, rcc_language_id language_id) {
if (rcc_default_ctx) ctx = rcc_default_ctx;
else return -1;
}
+
if ((language_id < 0)||(language_id >= ctx->n_languages)) return -1;
if ((!ctx->languages[language_id]->engines[0])||(!ctx->languages[language_id]->charsets[0])) return -2;
if (ctx->current_language != language_id) {
config = rccGetConfig(ctx, language_id);
- if (!config) return -1;
+ // NULL is Okey (Off), if (!config) return -1;
ctx->configure = 1;
ctx->current_language = language_id;
ctx->current_config = config;
}
+
+ return 0;
}
int rccSetLanguageByName(rcc_context ctx, const char *name) {
diff --git a/src/lng.h b/src/lng.h
index 87a9c91..7602e10 100644
--- a/src/lng.h
+++ b/src/lng.h
@@ -1,10 +1,14 @@
#ifndef _RCC_LNG_H
#define _RCC_LNG_H
+#include "internal.h"
#include "lngconfig.h"
rcc_language_ptr rccGetLanguagePointer(rcc_context ctx, rcc_language_id language_id);
-#define rccGetEnginePointer(ctx, engine_id) rccConfigGetEnginePointer(ctx->current_config, engine_id)
+#define rccGetCurrentEnginePointer(ctx) rccConfigGetCurrentEnginePointer(ctx->current_config)
+#define rccCheckCurrentEnginePointer(ctx) rccConfigCheckCurrentEnginePointer(ctx->current_config)
+#define rccGetEnginePointer(ctx,id) rccConfigGetEnginePointer(ctx->current_config, id)
+#define rccCheckEnginePointer(ctx,id) rccConfigCheckEnginePointer(ctx->current_config, id)
#endif /* _RCC_LNG_H */
diff --git a/src/lngconfig.c b/src/lngconfig.c
index 9748629..39fca76 100644
--- a/src/lngconfig.c
+++ b/src/lngconfig.c
@@ -8,22 +8,56 @@
rcc_engine_ptr rccConfigGetEnginePointer(rcc_language_config config, rcc_engine_id engine_id) {
unsigned int i;
rcc_engine_ptr *engines;
-
- if ((!config)||(!config->language)||(engine_id<0)) return NULL;
- engines = config->language->engines;
+ if ((!config)||(!config->language)||(engine_id<0)) return NULL;
+ if (engine_id == (rcc_engine_id)-1) return NULL;
+ engines = config->language->engines;
for (i=0;engines[i];i++);
if (engine_id>=i) return NULL;
return engines[engine_id];
}
+rcc_engine_ptr rccConfigCheckEnginePointer(rcc_language_config config, rcc_engine_id engine_id) {
+ rcc_engine_ptr engine;
+
+ engine = rccConfigGetEnginePointer(config, engine_id);
+ if ((engine)||(engine->func)) return engine;
+ return NULL;
+}
+
+rcc_engine_ptr rccConfigGetCurrentEnginePointer(rcc_language_config config) {
+ unsigned int i;
+ rcc_engine_id engine_id;
+ rcc_engine_ptr *engines;
+
+ engine_id = rccConfigGetCurrentEngine(config);
+ if (engine_id == (rcc_engine_id)-1) return NULL;
+
+ return rccConfigGetEnginePointer(config, engine_id);
+}
+
+rcc_engine_ptr rccConfigCheckCurrentEnginePointer(rcc_language_config config) {
+ rcc_engine_ptr engine;
+
+ engine = rccConfigGetCurrentEnginePointer(config);
+ if ((engine)||(engine->func)) return engine;
+ return NULL;
+}
+
+
const char *rccConfigGetEngineName(rcc_language_config config, rcc_engine_id engine_id) {
+ unsigned int i;
rcc_engine_ptr engine;
+
+ if ((!config)||(!config->language)||(engine_id<-1)) return NULL;
+ if (engine_id == (rcc_engine_id)-1) return rcc_engine_nonconfigured;
+
engine = rccConfigGetEnginePointer(config, engine_id);
if (!engine) return NULL;
+
return engine->title;
}
@@ -43,13 +77,16 @@ const char *rccConfigGetCharsetName(rcc_language_config config, rcc_charset_id c
const char *rccConfigGetAutoCharsetName(rcc_language_config config, rcc_charset_id charset_id) {
unsigned int i;
+ rcc_engine_id engine_id;
rcc_charset *charsets;
rcc_engine_ptr *engines;
if ((!config)||(!config->language)||(charset_id<0)) return NULL;
+ engine_id = rccConfigGetCurrentEngine(config);
+ if (engine_id == (rcc_engine_id)-1) return NULL;
engines = config->language->engines;
- charsets = engines[config->engine]->charsets;
+ charsets = engines[engine_id]->charsets;
for (i=0;charsets[i];i++);
if (charset_id>=i) return NULL;
@@ -62,11 +99,11 @@ rcc_engine_id rccConfigGetEngineByName(rcc_language_config config, const char *n
unsigned int i;
rcc_engine **engines;
- if ((!config)||(!config->language)||(!name)) return -1;
+ if ((!config)||(!config->language)||(!name)) return (rcc_engine_id)-1;
engines = config->language->engines;
for (i=0;engines[i];i++)
- if (!strcasecmp(engines[i]->title,name)) return i;
+ if (!strcasecmp(engines[i]->title,name)) return (rcc_engine_id)i;
return (rcc_engine_id)-1;
}
@@ -86,17 +123,21 @@ rcc_charset_id rccConfigGetCharsetByName(rcc_language_config config, const char
rcc_charset_id rccConfigGetAutoCharsetByName(rcc_language_config config, const char *name) {
unsigned int i;
+ rcc_engine_id engine_id;
rcc_charset *charsets;
rcc_engine_ptr *engines;
if ((!config)||(!config->language)||(!name)) return (rcc_charset_id)-1;
+
+ engine_id = rccConfigGetCurrentEngine(config);
+ if (engine_id == (rcc_engine_id)-1) return (rcc_charset_id)-1;
engines = config->language->engines;
- charsets = engines[config->engine]->charsets;
+ charsets = engines[engine_id]->charsets;
for (i=0;charsets[i];i++)
if (!strcasecmp(charsets[i],name)) return (rcc_charset_id)i;
-
+
return (rcc_charset_id)-1;
}
@@ -132,7 +173,7 @@ rcc_language_config rccCheckConfig(rcc_context ctx, rcc_language_id language_id)
int err;
new_language_id = rccGetRealLanguage(ctx, language_id);
- if ((language_id == (rcc_language_id)-1)||(new_language_id != language_id)) return NULL;
+ if ((new_language_id == (rcc_language_id)-1)||(new_language_id != language_id)) return NULL;
if (!ctx->configs[language_id].charset) return NULL;
if (!strcasecmp(ctx->languages[language_id]->sn, "off")) return NULL;
@@ -144,6 +185,8 @@ rcc_language_config rccGetConfig(rcc_context ctx, rcc_language_id language_id) {
language_id = rccGetRealLanguage(ctx, language_id);
if (language_id == (rcc_language_id)-1) return NULL;
+ if (!strcasecmp(ctx->languages[language_id]->sn, "off")) return NULL;
+
if (!ctx->configs[language_id].charset) {
if (rccConfigInit(ctx->configs+language_id, ctx)) return NULL;
}
@@ -190,6 +233,8 @@ rcc_engine_id rccConfigGetCurrentEngine(rcc_language_config config) {
rcc_engine **enginelist;
rcc_engine_id engine_id;
+ if (!config) return (rcc_engine_id)-1;
+
engine_id = rccConfigGetSelectedEngine(config);
if (engine_id != (rcc_engine_id)-1) return engine_id;
@@ -213,7 +258,7 @@ const char *rccConfigGetCurrentEngineName(rcc_language_config config) {
}
rcc_charset_id rccConfigGetSelectedCharset(rcc_language_config config, rcc_class_id class_id) {
- if ((!config)||(!config->ctx)||(class_id<0)||(class_id>=config->ctx->n_classes)) return -1;
+ if ((!config)||(!config->ctx)||(class_id<0)||(class_id>=config->ctx->n_classes)) return (rcc_charset_id)-1;
return config->charset[class_id];
}
@@ -232,6 +277,9 @@ rcc_charset_id rccConfigGetCurrentCharset(rcc_language_config config, rcc_class_
unsigned int i;
rcc_charset_id charset_id;
+ rcc_class_default_charset *defcharset;
+ const char *lang;
+
rcc_language *language;
rcc_class_ptr *classes;
rcc_charset *charsets;
@@ -262,7 +310,17 @@ rcc_charset_id rccConfigGetCurrentCharset(rcc_language_config config, rcc_class_
charset_id = rccConfigGetLocaleCharset(config, defvalue);
if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) return charset_id;
-
+
+ defcharset = cl->defcharset;
+ if (defcharset) {
+ lang = config->language->sn;
+
+ for (i = 0; cl->defcharset[i].lang; i++) {
+ if (!strcasecmp(lang, defcharset[i].lang))
+ return rccConfigGetCharsetByName(config, defcharset[i].charset);
+ }
+ }
+
charsets=language->charsets;
if ((charsets[0])&&(charsets[1])) return (rcc_charset_id)1;
return (rcc_charset_id)-1;
diff --git a/src/lngconfig.h b/src/lngconfig.h
index 4e9681c..64ca523 100644
--- a/src/lngconfig.h
+++ b/src/lngconfig.h
@@ -1,6 +1,7 @@
#ifndef _RCC_LNGCONFIG_H
#define _RCC_LNGCONFIG_H
+
struct rcc_language_config_t {
rcc_context ctx;
rcc_language *language;
@@ -10,7 +11,11 @@ struct rcc_language_config_t {
};
typedef struct rcc_language_config_t rcc_language_config_s;
+
rcc_engine_ptr rccConfigGetEnginePointer(rcc_language_config config, rcc_engine_id engine_id);
+rcc_engine_ptr rccConfigCheckEnginePointer(rcc_language_config config, rcc_engine_id engine_id);
+rcc_engine_ptr rccConfigGetCurrentEnginePointer(rcc_language_config config);
+rcc_engine_ptr rccConfigCheckCurrentEnginePointer(rcc_language_config config);
int rccConfigInit(rcc_language_config config, rcc_context ctx);
int rccConfigFree(rcc_language_config config);
diff --git a/src/opt.h b/src/opt.h
index c10a53d..efea382 100644
--- a/src/opt.h
+++ b/src/opt.h
@@ -7,4 +7,23 @@ struct rcc_option_defval_t {
};
typedef struct rcc_option_defval_t rcc_option_defval;
+enum rcc_option_type_t {
+ RCC_OPTION_TYPE_BOOLEAN = 0,
+ RCC_OPTION_TYPE_RANGE,
+ RCC_OPTION_TYPE_FLAGS,
+ RCC_OPTION_TYPE_MENU
+};
+typedef enum rcc_option_type_t rcc_option_type;
+
+struct rcc_option_description_t {
+ rcc_option option;
+ const char *sn;
+ rcc_option_type;
+ rcc_option_value min;
+ rcc_option_value max;
+
+};
+typedef struct rcc_option_description_t rcc_option_description;
+
+
#endif /* _RCC_OPT_H */
diff --git a/src/plugin.c b/src/plugin.c
index a50bff3..7935491 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -22,6 +22,7 @@ rcc_library_handle rccLibraryOpen(char *filename)
void rccLibraryClose(rcc_library_handle handle)
{
#ifdef RCC_PLUGINS
+ puts("HHHHHHHHHHHHHHHHHHHH");
dlclose(handle);
#endif /* RCC_PLUGINS */
}
diff --git a/src/rccconfig.c b/src/rccconfig.c
index e1ac34a..d40941f 100644
--- a/src/rccconfig.c
+++ b/src/rccconfig.c
@@ -1,14 +1,10 @@
#include <stdio.h>
-#include <librcd.h>
#include "internal.h"
#include "rccconfig.h"
+#include "engine.h"
#include "opt.h"
-static rcc_charset_id rcc_autoengine_russian(rcc_engine_context ctx, const char *buf, int len) {
- return (rcc_charset_id)rcdGetRussianCharset(buf,len);
-}
-
rcc_language_alias rcc_default_aliases[] = {
{ "cs_SK", "sk" },
{ "ru_UA", "uk" },
@@ -23,7 +19,7 @@ rcc_engine rcc_default_engine = {
};
rcc_engine rcc_russian_engine = {
- "Russian", NULL, NULL, &rcc_autoengine_russian, {"CP1251","KOI8-R","UTF-8","IBM866", NULL}
+ "Russian", NULL, NULL, &rccAutoengineRussian, {"CP1251","KOI8-R","UTF-8","IBM866", NULL}
};
rcc_language rcc_default_languages[RCC_MAX_LANGUAGES + 1] = {
@@ -37,12 +33,16 @@ rcc_language rcc_default_languages[RCC_MAX_LANGUAGES + 1] = {
}},
{"ru", {"Default","KOI8-R","CP1251","UTF-8","IBM866","MACCYRILLIC","ISO8859-5", NULL}, {
&rcc_default_engine,
+#ifdef RCC_RCD_SUPPORT
&rcc_russian_engine,
+#endif /* RCC_RCD_SUPPORT */
NULL
}},
{"uk", {"Default","KOI8-U","CP1251","UTF-8","IBM855","MACCYRILLIC","ISO8859-5","CP1125", NULL}, {
&rcc_default_engine,
+#ifdef RCC_RCD_SUPPORT
&rcc_russian_engine,
+#endif /* RCC_RCD_SUPPORT */
NULL
}},
{"be", {"Default", "UTF-8", "CP1251", "IBM866", "ISO-8859-5", "KOI8-UNI", "maccyr" "IBM855", NULL},{
@@ -116,6 +116,13 @@ rcc_language_name rcc_default_language_names[RCC_MAX_LANGUAGES+1] = {
{NULL, NULL}
};
+rcc_option_description rcc_default_option_descriptions[] = {
+ {RCC_LEARNING_MODE, "LEARNING_MODE", RCC_OPTION_TYPE_BOOLEAN, 0, 0},
+ {RCC_AUTODETECT_FS_TITLES, "AUTODETECT_FS_TITLES", RCC_OPTION_TYPE_BOOLEAN, 0, 0},
+ {RCC_AUTODETECT_FS_NAMES, "AUTODETECT_FS_NAMES", RCC_OPTION_TYPE_NAMES;
+ {RCC_AUTODETECT_FS_TITLES, "AUTODETECT_FS_TITLES", RCC_OPTION_TYPE_NAMES;
+ RCC_CONFIGURED_LANGUAGES_ONLY
+
rcc_option_name rcc_default_option_names[] = {
{ RCC_LEARNING_MODE, "Learning Mode", "LEARNING_MODE" },
{ RCC_AUTODETECT_FS_TITLES, "Autodetect FS Encoding", "AUTODETECT_FS_TITLES" },
@@ -127,6 +134,7 @@ rcc_option_defval rcc_default_option_values[] = {
{ RCC_LEARNING_MODE, 0 },
{ RCC_AUTODETECT_FS_TITLES, 1},
{ RCC_AUTODETECT_FS_NAMES, 1},
+ { RCC_CONFIGURED_LANGUAGES_ONLY, 1},
{ RCC_MAX_OPTIONS, 0}
};
diff --git a/src/rccdb4.c b/src/rccdb4.c
new file mode 100644
index 0000000..795b721
--- /dev/null
+++ b/src/rccdb4.c
@@ -0,0 +1,124 @@
+#include <stdio.h>
+
+#include "internal.h"
+#include "rccdb4.h"
+
+#define DATABASE "autolearn.db"
+#define MIN_CHARS 3
+
+int rccInitDb4(rcc_context ctx, const char *name, rcc_db4_flags flags) {
+ size_t size;
+ char *dbname;
+
+ if (!ctx) {
+ if (rcc_default_ctx) ctx = rcc_default_ctx;
+ else return -1;
+ }
+
+ if (!name) name = "default";
+
+ size = strlen(rcc_home_dir) + strlen(name) + 32;
+ dbname = (char*)malloc(size*sizeof(char));
+ if (!dbname) return -1;
+
+ sprintf(dbname,"%s/.rcc/",rcc_home_dir);
+ mkdir(dbname, 00644);
+
+ sprintf(dbname,"%s/.rcc/%s.db/",rcc_home_dir,name);
+ mkdir(dbname, 00644);
+
+ ctx->db4ctx = rccDb4CreateContext(dbname, flags);
+ free(dbname);
+
+ if (!ctx->db4ctx) return -1;
+
+ return 0;
+}
+
+db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) {
+ int err;
+ db4_context ctx;
+ DB_ENV *dbe;
+ DB *db;
+
+ err = db_env_create(&dbe, 0);
+ if (err) return NULL;
+
+ err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 0);
+ if (err) {
+ dbe->close(dbe, 0);
+ return NULL;
+ }
+
+ err = db_create(&db, dbe, 0);
+ if (err) {
+ dbe->close(dbe, 0);
+ return NULL;
+ }
+
+ err = db->open(db, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
+ if (err) {
+ db->close(db, 0);
+ dbe->close(dbe, 0);
+ return NULL;
+ }
+
+ ctx = (db4_context)malloc(sizeof(db4_context_s));
+ if (!ctx) {
+ db->close(db, 0);
+ dbe->close(dbe, 0);
+ return NULL;
+ }
+
+ ctx->db = db;
+ ctx->dbe = dbe;
+ ctx->flags = flags;
+ return ctx;
+}
+
+void rccDb4FreeContext(db4_context ctx) {
+ if (ctx) {
+ ctx->db->close(ctx->db, 0);
+ ctx->dbe->close(ctx->dbe, 0);
+ free(ctx);
+ }
+}
+
+int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string, size_t slen) {
+ int err;
+ DBT key, data;
+
+ if ((!ctx)||(!orig)||(!string)) return -1;
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ key.data = (char*)orig;
+ key.size = STRNLEN(orig, olen);
+ data.data = (char*)string;
+ data.size = STRNLEN(string, slen);
+
+ if (key.size < MIN_CHARS) return -1;
+
+ err = ctx->db->put(ctx->db, NULL, &key, &data, 0);
+ return err;
+}
+
+rcc_string rccDb4GetKey(db4_context ctx, const char *orig, size_t olen) {
+ int err;
+ DBT key, data;
+
+ if ((!ctx)||(!orig)) return NULL;
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ key.data = (char*)orig;
+ key.size = STRNLEN(orig, olen);
+
+ data.flags = DB_DBT_REALLOC;
+
+ err = ctx->db->get(ctx->db, NULL, &key, &data, 0);
+ if (err) return NULL;
+ return data.data;
+}
diff --git a/src/rccdb4.h b/src/rccdb4.h
new file mode 100644
index 0000000..0fb55b7
--- /dev/null
+++ b/src/rccdb4.h
@@ -0,0 +1,23 @@
+#ifndef _RCC_DB4_H
+#define _RCC_DB4_H
+
+#include <db.h>
+#include "rccstring.h"
+
+struct db4_context_t {
+ DB_ENV *dbe;
+ DB *db;
+
+ rcc_db4_flags flags;
+};
+
+typedef struct db4_context_t db4_context_s;
+typedef struct db4_context_t *db4_context;
+
+db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags);
+void rccDb4FreeContext(db4_context ctx);
+
+int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string, size_t slen);
+rcc_string rccDb4GetKey(db4_context ctx, const char *orig, size_t olen);
+
+#endif /* _RCC_DB4_H */
diff --git a/src/rccenca.c b/src/rccenca.c
index 1aabf7a..8a439bc 100644
--- a/src/rccenca.c
+++ b/src/rccenca.c
@@ -56,18 +56,17 @@ rcc_charset_id rccEnca(rcc_engine_context ctx, const char *buf, int len) {
EncaEncoding ee;
internal = rccEngineGetInternal(ctx);
- if ((!internal)||(!buf)) return -1;
-
+ if ((!internal)||(!buf)) return (rcc_charset_id)-1;
len = STRNLEN(buf, len);
ee = enca_analyse_const((EncaAnalyser)ctx->internal,buf,len);
- if (ee.charset<0) return -1;
+ if (ee.charset<0) return (rcc_charset_id)-1;
charset = enca_charset_name(ee.charset, ENCA_NAME_STYLE_ICONV);
return rccGetAutoCharsetByName(ctx->ctx, charset);
#else /* RCC_ENCA_SUPPORT */
- return -1;
+ return (rcc_charset_id)-1;
#endif /* RCC_ENCA_SUPPORT */
}
@@ -107,6 +106,7 @@ static int rccEncaLibraryLoad() {
# ifdef RCC_DEBUG
perror( "rccEnca. Incomplete function set in library" );
# endif /* RCC_DEBUG */
+ return -1;
}
#endif /* RCC_ENCA_DYNAMIC */
@@ -116,7 +116,7 @@ static int rccEncaLibraryLoad() {
static void rccEncaLibraryUnload() {
#ifdef RCC_ENCA_DYNAMIC
if (enca_handle) {
- rccLibraryUnload(enca_handle);
+ rccLibraryClose(enca_handle);
enca_handle = NULL;
}
#endif /* RCC_ENCA_DYNAMIC */
@@ -130,15 +130,16 @@ int rccEncaInit() {
int *charsets;
size_t n_charsets;
+ const char *charset;
#ifdef RCC_ENCA_SUPPORT
- if (enca_engines) return -1;
+ if (enca_engines) return 0;
for (i=0;rcc_default_languages[i].sn;i++);
enca_engines = (rcc_engine*)malloc(i*sizeof(rcc_engine));
if (!enca_engines) return -1;
err = rccEncaLibraryLoad();
- if (err) return err;
+ if (err) return 0;
for (i=0;rcc_default_languages[i].sn;i++) {
engines = rcc_default_languages[i].engines;
@@ -152,10 +153,15 @@ int rccEncaInit() {
if (charsets) {
memcpy(enca_engines+i, &rcc_enca_engine, sizeof(rcc_engine));
for (k=0;enca_engines[i].charsets[k];k++);
+
if (n_charsets+k>=RCC_MAX_CHARSETS) n_charsets = RCC_MAX_CHARSETS-k;
- for (l=0;l<n_charsets;l++)
- enca_engines[j].charsets[k++] = enca_charset_name(charsets[l], ENCA_NAME_STYLE_ICONV);
+ for (l=0;l<n_charsets;l++) {
+ // Enca bug, STYLE_ICONV return's a lot of NULL's
+ charset = enca_charset_name(charsets[l], ENCA_NAME_STYLE_ICONV);
+ if (!charset) charset = enca_charset_name(charsets[l], ENCA_NAME_STYLE_ENCA);
+ enca_engines[i].charsets[k++] = charset;
+ }
enca_engines[j].charsets[k] = NULL;
engines[j] = enca_engines + i;
diff --git a/src/rccxml.c b/src/rccxml.c
index a64e759..7227dbd 100644
--- a/src/rccxml.c
+++ b/src/rccxml.c
@@ -14,8 +14,6 @@
#include "internal.h"
#include "rccconfig.h"
-extern char *rcc_home_dir;
-
#define MAX_HOME_CHARS 96
#define XPATH_LANGUAGE "//Language[@name]"
@@ -149,6 +147,8 @@ static xmlNodePtr rccNodeFind(xmlXPathContextPtr xpathctx, const char *request,
unsigned int size = 64;
va_list ap;
char *req;
+
+ if (!xpathctx) return NULL;
for (req = strstr(request, "%s"); req; req = strstr(req + 1, "%s")) args++;
@@ -358,7 +358,7 @@ clear:
int rccLoad(rcc_context ctx, const char *name) {
int err;
- int fd;
+ int fd, sysfd;
char *config;
struct stat st;
@@ -372,8 +372,8 @@ int rccLoad(rcc_context ctx, const char *name) {
rcc_class_ptr *classes;
rcc_class_ptr cl;
- xmlXPathContextPtr xpathctx;
- xmlDocPtr doc = NULL;
+ xmlXPathContextPtr xpathctx = NULL, sysxpathctx = NULL, curxpathctx;
+ xmlDocPtr doc = NULL, sysdoc = NULL;
xmlNodePtr node, lnode;
if (!ctx) {
@@ -389,17 +389,52 @@ int rccLoad(rcc_context ctx, const char *name) {
sprintf(config,"%s/.rcc/%s.xml",rcc_home_dir,name);
fd = open(config, O_RDONLY);
- if (fd == -1) goto clear;
- flock(fd, LOCK_EX);
+
+ sprintf(config, "/etc/rcc/%s.xml",name);
+ sysfd = open(config, O_RDONLY);
- if ((!fstat(fd, &st))&&(st.st_size)) {
- doc = xmlReadFd(fd, config, NULL, 0);
- } else goto clear;
+ free(config);
+
+ if (fd != -1) {
+ flock(fd, LOCK_EX);
+ if ((!fstat(fd, &st))&&(st.st_size)) {
+ doc = xmlReadFd(fd, name, NULL, 0);
+ }
+ flock(fd, LOCK_UN);
+ close(fd);
- xpathctx = xmlXPathNewContext(doc);
- if (!xpathctx) goto clear;
+ if (doc) {
+ xpathctx = xmlXPathNewContext(doc);
+ if (!xpathctx) {
+ xmlFreeDoc(doc);
+ doc = NULL;
+ }
+ }
+ }
+
+ if (sysfd != -1) {
+ flock(sysfd, LOCK_EX);
+ if ((!fstat(sysfd, &st))&&(st.st_size)) {
+ sysdoc = xmlReadFd(sysfd, name, NULL, 0);
+ }
+ flock(sysfd, LOCK_UN);
+ close(sysfd);
+
+ if (sysdoc) {
+ sysxpathctx = xmlXPathNewContext(sysdoc);
+ if (!sysxpathctx) {
+ xmlFreeDoc(sysdoc);
+ sysdoc = NULL;
+ }
+ }
+ }
+
+ if ((!doc)&&(!sysdoc)) goto clear;
+
+
node = rccNodeFind(xpathctx, XPATH_SELECTED_LANGUAGE);
+ if (!node) node = rccNodeFind(sysxpathctx, XPATH_SELECTED_LANGUAGE);
if (node) {
tmp = rccXmlGetText(node);
if (tmp) err = rccSetLanguageByName(ctx, tmp);
@@ -412,6 +447,7 @@ int rccLoad(rcc_context ctx, const char *name) {
if (!oname) continue;
node = rccNodeFind(xpathctx, XPATH_SELECTED_OPTION, oname);
+ if (!node) node = rccNodeFind(sysxpathctx, XPATH_SELECTED_OPTION, oname);
if (node) {
tmp = rccXmlGetText(node);
if ((tmp)&&(strcasecmp(tmp,rcc_option_nonconfigured))) err = rccSetOption(ctx, (rcc_option)i, (rcc_option_value)atoi(tmp));
@@ -427,12 +463,17 @@ int rccLoad(rcc_context ctx, const char *name) {
language = languages[i];
lnode = rccNodeFind(xpathctx, XPATH_SELECTED_LANG, language->sn);
- if (!lnode) continue;
+ if (lnode) curxpathctx = xpathctx;
+ else {
+ lnode = rccNodeFind(sysxpathctx, XPATH_SELECTED_LANG, language->sn);
+ if (lnode) curxpathctx = sysxpathctx;
+ else continue;
+ }
cfg = rccGetConfig(ctx, (rcc_language_id)i);
if (!cfg) continue;
- node = rccNodeFind(xpathctx, XPATH_SELECTED_ENGINE, language->sn);
+ node = rccNodeFind(curxpathctx, XPATH_SELECTED_ENGINE, language->sn);
if (node) {
tmp = rccXmlGetText(node);
if (tmp) err = rccConfigSetEngineByName(cfg, tmp);
@@ -443,7 +484,7 @@ int rccLoad(rcc_context ctx, const char *name) {
for (j=0;classes[j];j++) {
cl = classes[j];
- node = rccNodeFind(xpathctx, XPATH_SELECTED_CLASS, language->sn, cl->name);
+ node = rccNodeFind(curxpathctx, XPATH_SELECTED_CLASS, language->sn, cl->name);
if (node) {
tmp = rccXmlGetText(node);
if (tmp) err = rccConfigSetCharsetByName(cfg, (rcc_class_id)j, tmp);
@@ -454,18 +495,24 @@ int rccLoad(rcc_context ctx, const char *name) {
}
clear:
- if (config) {
- if (fd != -1) {
- if (doc) {
- if (xpathctx) {
- xmlXPathFreeContext(xpathctx);
- }
- xmlFreeDoc(doc);
- }
- close(fd);
+
+ if (sysdoc) {
+ if (sysxpathctx) {
+ xmlXPathFreeContext(sysxpathctx);
}
- free(config);
+ xmlFreeDoc(sysdoc);
+ }
+ if (doc) {
+ if (xpathctx) {
+ xmlXPathFreeContext(xpathctx);
+ }
+ xmlFreeDoc(doc);
}
+ if ((!ctx->current_language)&&(rccGetOption(ctx, RCC_CONFIGURED_LANGUAGES_ONLY))) {
+ ctx->current_config = rccGetCurrentConfig(ctx);
+ ctx->configure = 1;
+ }
+
return 0;
}
diff --git a/src/recode.c b/src/recode.c
index 4c1c5bd..f071f33 100644
--- a/src/recode.c
+++ b/src/recode.c
@@ -8,6 +8,7 @@
#include "lng.h"
#include "rccstring.h"
#include "rccconfig.h"
+#include "rccdb4.h"
@@ -20,8 +21,8 @@ static rcc_charset_id rccIConvAuto(rcc_context ctx, rcc_class_id class_id, const
class_type = rccGetClassType(ctx, class_id);
if ((class_type == RCC_CLASS_STANDARD)||((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_TITLES)))) {
- engine = rccGetEnginePointer(ctx, rccGetCurrentEngine(ctx));
- if ((!engine)||(!engine->func)||(!strcasecmp(engine->title, "off"))||(!strcasecmp(engine->title, "dissable"))) return -1;
+ engine = rccGetCurrentEnginePointer(ctx);
+ if ((!engine)||(!engine->func)) return (rcc_charset_id)-1;
return engine->func(&ctx->engine_ctx, buf, len);
}
@@ -42,6 +43,13 @@ rcc_string rccFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, size
}
if ((class_id<0)||(class_id>=ctx->n_classes)||(!buf)) return NULL;
+
+ string = rccDb4GetKey(ctx->db4ctx, buf, len);
+ if (string) {
+ puts("Got a string");
+ return string;
+ }
+
err = rccConfigure(ctx);
if (err) return NULL;
@@ -50,7 +58,7 @@ rcc_string rccFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, size
if (ret) return NULL;
language_id = rccGetCurrentLanguage(ctx);
- // DS: Learning. check database (language_id)
+ // DS: Learning. check database (language_id, check if language_id initialized)
charset_id = rccIConvAuto(ctx, class_id, buf, len);
if (charset_id != (rcc_charset_id)-1) icnv = ctx->iconv_auto[charset_id];
@@ -96,8 +104,10 @@ char *rccTo(rcc_context ctx, rcc_class_id class_id, const rcc_string buf, size_t
language_id = rccStringGetLanguage(buf);
utfstring = rccStringGetString(buf);
+ /* COnfigure is only required in case of current language */
err = rccConfigure(ctx);
if (err) return NULL;
+ /* Do something even in case of error (Language can be changed) */
icnv = ctx->iconv_to[class_id];
diff --git a/ui/gtk.c b/ui/gtk.c
index c8e3a59..2fdf2f4 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -126,7 +126,7 @@ int rccUiMenuConfigureWidget(rcc_ui_menu_context ctx) {
config = rccGetConfig(rccctx, language_id);
charset_id = rccConfigGetSelectedCharset(config, (rcc_class_id)ctx->id);
- if (charset_id < 0) charset_id = 0;
+ if (charset_id == (rcc_charset_id)-1) charset_id = 0;
gtk_option_menu_set_history(GTK_OPTION_MENU(menu), charset_id);
break;
case RCC_UI_MENU_ENGINE:
@@ -148,12 +148,10 @@ int rccUiMenuConfigureWidget(rcc_ui_menu_context ctx) {
gtk_option_menu_remove_menu(GTK_OPTION_MENU(menu));
gtk_option_menu_set_menu(GTK_OPTION_MENU(menu), list);
-
config = rccGetConfig(rccctx, language_id);
engine_id = rccConfigGetCurrentEngine(config);
- if (engine_id < 0) engine_id = 0;
+ if (engine_id == (rcc_engine_id)-1) engine_id = 0;
gtk_option_menu_set_history(GTK_OPTION_MENU(menu), engine_id);
-
break;
case RCC_UI_MENU_OPTION:
if (!ctx->widget) {
diff --git a/ui/librccui.c b/ui/librccui.c
index c868708..3b8bcdc 100644
--- a/ui/librccui.c
+++ b/ui/librccui.c
@@ -165,12 +165,9 @@ int rccUiRestoreLanguage(rcc_ui_context ctx) {
rcc_class_ptr *classes;
rcc_language_id language_id;
- rcc_language_config config;
-
if (!ctx) return -1;
language_id = (rcc_language_id)rccUiMenuGet(ctx->language);
- config = rccGetConfig(ctx->rccctx, language_id);
rccUiMenuConfigureWidget(ctx->engine);
//rccUiMenuSet(ctx->engine, (rcc_ui_id)rccConfigGetSelectedEngine(config));
@@ -386,6 +383,7 @@ rcc_ui_frame rccUiGetEngineFrame(rcc_ui_context ctx, const char *title) {
rcc_ui_frame frame;
rcc_ui_box engine;
rcc_ui_box opt;
+ const char *optname;
if (!ctx) return NULL;
@@ -400,7 +398,10 @@ rcc_ui_frame rccUiGetEngineFrame(rcc_ui_context ctx, const char *title) {
rccUiFrameAdd(framectx, engine);
for (i=0; i<RCC_MAX_OPTIONS; i++) {
- opt = rccUiGetOptionBox(ctx, (rcc_option)i, rccUiGetOptionName(ctx, i));
+ optname = rccUiGetOptionName(ctx, i);
+ if (!optname) continue;
+
+ opt = rccUiGetOptionBox(ctx, (rcc_option)i, optname);
rccUiFrameAdd(framectx, opt);
}
diff --git a/ui/rccnames.c b/ui/rccnames.c
index 2e11165..f5bf4d8 100644
--- a/ui/rccnames.c
+++ b/ui/rccnames.c
@@ -40,5 +40,5 @@ const char *rccUiGetOptionName(rcc_ui_context ctx, rcc_option option) {
res = rccGetOptionFullName(option);
if (res) return res;
- return "";
+ return NULL;
}