summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamil Kalimullin <ramil@mysql.com>2010-11-18 13:40:57 +0300
committerRamil Kalimullin <ramil@mysql.com>2010-11-18 13:40:57 +0300
commite4d2fd35a7333fb6a9c92c6439b4c4123983ccde (patch)
treef67f4a6e2fd2e3828a0321bbd2b1c6ffc5f0d220
parent1c94d43bbb60817252a87453d3a1d1a7d0f2a35c (diff)
parentc324624291a8c7cfbfcc728ce9fa86feb8d4e904 (diff)
downloadmariadb-git-e4d2fd35a7333fb6a9c92c6439b4c4123983ccde.tar.gz
Auto-merge from mysql-5.1-bugteam.
-rw-r--r--.bzrignore9
-rwxr-xr-xBUILD/compile-pentium-mysqlfs-debug2
-rw-r--r--Makefile.am2
-rw-r--r--README94
-rw-r--r--cmd-line-utils/readline/bind.c2
-rw-r--r--config/ac-macros/maintainer.m41
-rw-r--r--configure.in45
-rw-r--r--include/m_string.h4
-rw-r--r--include/my_compiler.h5
-rw-r--r--include/mysql_embed.h1
-rw-r--r--libmysql/libmysql.c4
-rw-r--r--mysql-test/collections/default.weekly2
-rw-r--r--mysql-test/collections/mysql-5.1-bugteam.daily5
-rw-r--r--mysql-test/collections/mysql-5.1-bugteam.push4
-rw-r--r--mysql-test/lib/mtr_cases.pm21
-rwxr-xr-xmysql-test/mysql-test-run.pl58
-rw-r--r--mysql-test/r/func_time.result14
-rw-r--r--mysql-test/r/log_tables.result10
-rw-r--r--mysql-test/r/sp-bugs.result36
-rw-r--r--mysql-test/r/type_blob.result11
-rw-r--r--mysql-test/r/variables-big.result10
-rw-r--r--mysql-test/suite/binlog/t/binlog_index-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt1
-rwxr-xr-xmysql-test/suite/ibmdb2i/include/have_i54.inc20
-rw-r--r--mysql-test/suite/ibmdb2i/include/have_i61.inc20
-rw-r--r--mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc6
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result11
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result4
-rwxr-xr-xmysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result4
-rwxr-xr-xmysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result18
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result33
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result7
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result20
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result9
-rw-r--r--mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result1204
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test9
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test9
-rwxr-xr-xmysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test8
-rwxr-xr-xmysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test28
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test26
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test11
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test47
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test10
-rw-r--r--mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test44
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result8
-rw-r--r--mysql-test/suite/innodb/t/innodb_mysql.test13
-rw-r--r--mysql-test/suite/parts/inc/partition_auto_increment.inc49
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_blackhole.result32
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_innodb.result72
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_memory.result72
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_myisam.result72
-rw-r--r--mysql-test/suite/parts/t/part_supported_sql_func_innodb.test3
-rw-r--r--mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test3
-rw-r--r--mysql-test/suite/parts/t/partition_alter1_2_innodb.test3
-rw-r--r--mysql-test/suite/parts/t/partition_alter4_innodb.test3
-rw-r--r--mysql-test/suite/rpl/r/rpl_ignore_table.result1
-rw-r--r--mysql-test/suite/rpl/t/rpl_cross_version-master.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_current_user-master.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_ignore_table.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh1
-rw-r--r--mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh1
-rw-r--r--mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/README3
-rw-r--r--mysql-test/suite/sys_vars/inc/timestamp_basic.inc4
-rw-r--r--mysql-test/suite/sys_vars/r/general_log_file_basic.result5
-rw-r--r--mysql-test/suite/sys_vars/r/general_log_func.result2
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result46
-rw-r--r--mysql-test/suite/sys_vars/r/log_output_basic.result4
-rw-r--r--mysql-test/suite/sys_vars/r/log_output_func.result3
-rw-r--r--mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result4
-rw-r--r--mysql-test/suite/sys_vars/r/timestamp_basic_32.result12
-rw-r--r--mysql-test/suite/sys_vars/r/timestamp_basic_64.result16
-rw-r--r--mysql-test/suite/sys_vars/r/tmp_table_size_basic.result2
-rw-r--r--mysql-test/suite/sys_vars/t/completion_type_func.test2
-rw-r--r--mysql-test/suite/sys_vars/t/disabled.def13
-rw-r--r--mysql-test/suite/sys_vars/t/general_log_file_basic.test6
-rw-r--r--mysql-test/suite/sys_vars/t/general_log_func.test2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test18
-rw-r--r--mysql-test/suite/sys_vars/t/log_output_func.test6
-rw-r--r--mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test3
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_init_slave_func.test2
-rw-r--r--mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test8
-rw-r--r--mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/timestamp_basic_32.test4
-rw-r--r--mysql-test/suite/sys_vars/t/timestamp_basic_64.test5
-rw-r--r--mysql-test/suite/sys_vars/t/tmp_table_size_basic.test3
-rw-r--r--mysql-test/t/disabled.def2
-rw-r--r--mysql-test/t/func_time.test10
-rw-r--r--mysql-test/t/key_cache-master.opt1
-rw-r--r--mysql-test/t/log_tables.test19
-rw-r--r--mysql-test/t/mysqlbinlog-master.opt1
-rw-r--r--mysql-test/t/sp-bugs.test37
-rw-r--r--mysql-test/t/type_blob.test16
-rw-r--r--mysql-test/t/variables-big.test10
-rw-r--r--mysys/mf_keycache.c10
-rw-r--r--mysys/my_getncpus.c3
-rw-r--r--mysys/stacktrace.c4
-rw-r--r--pstack/Makefile.am32
-rw-r--r--pstack/aout/Makefile.am4
-rw-r--r--pstack/aout/aout64.h475
-rw-r--r--pstack/aout/stab.def264
-rw-r--r--pstack/aout/stab_gnu.h37
-rw-r--r--pstack/bucomm.c238
-rw-r--r--pstack/bucomm.h91
-rw-r--r--pstack/budbg.h64
-rw-r--r--pstack/debug.c3509
-rw-r--r--pstack/debug.h798
-rw-r--r--pstack/demangle.h90
-rw-r--r--pstack/filemode.c266
-rw-r--r--pstack/ieee.c7602
-rw-r--r--pstack/ieee.h138
-rw-r--r--pstack/libiberty.h180
-rw-r--r--pstack/linuxthreads.c90
-rw-r--r--pstack/linuxthreads.h28
-rw-r--r--pstack/pstack.c2746
-rw-r--r--pstack/pstack.h22
-rw-r--r--pstack/pstacktrace.h24
-rw-r--r--pstack/rddbg.c462
-rw-r--r--pstack/stabs.c5082
-rw-r--r--regex/regexec.c5
-rw-r--r--sql/Makefile.am1
-rw-r--r--sql/debug_sync.cc2
-rw-r--r--sql/ha_partition.cc37
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/item_timefunc.h1
-rw-r--r--sql/mysqld.cc26
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_partition.cc4
-rw-r--r--sql/sql_rename.cc6
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc6
-rw-r--r--sql/sql_table.cc4
-rw-r--r--storage/ibmdb2i/CMakeLists.txt25
-rw-r--r--storage/ibmdb2i/Makefile.am54
-rw-r--r--storage/ibmdb2i/db2i_blobCollection.cc107
-rw-r--r--storage/ibmdb2i/db2i_blobCollection.h151
-rw-r--r--storage/ibmdb2i/db2i_charsetSupport.cc826
-rw-r--r--storage/ibmdb2i/db2i_charsetSupport.h65
-rw-r--r--storage/ibmdb2i/db2i_collationSupport.cc355
-rw-r--r--storage/ibmdb2i/db2i_collationSupport.h48
-rw-r--r--storage/ibmdb2i/db2i_constraints.cc672
-rw-r--r--storage/ibmdb2i/db2i_conversion.cc1459
-rw-r--r--storage/ibmdb2i/db2i_errors.cc297
-rw-r--r--storage/ibmdb2i/db2i_errors.h93
-rw-r--r--storage/ibmdb2i/db2i_file.cc556
-rw-r--r--storage/ibmdb2i/db2i_file.h445
-rw-r--r--storage/ibmdb2i/db2i_global.h138
-rw-r--r--storage/ibmdb2i/db2i_iconv.h51
-rw-r--r--storage/ibmdb2i/db2i_ileBridge.cc1342
-rw-r--r--storage/ibmdb2i/db2i_ileBridge.h499
-rw-r--r--storage/ibmdb2i/db2i_ioBuffers.cc332
-rw-r--r--storage/ibmdb2i/db2i_ioBuffers.h416
-rw-r--r--storage/ibmdb2i/db2i_misc.h129
-rw-r--r--storage/ibmdb2i/db2i_myconv.cc1498
-rw-r--r--storage/ibmdb2i/db2i_myconv.h3201
-rw-r--r--storage/ibmdb2i/db2i_rir.cc686
-rw-r--r--storage/ibmdb2i/db2i_safeString.h98
-rw-r--r--storage/ibmdb2i/db2i_sqlStatementStream.cc86
-rw-r--r--storage/ibmdb2i/db2i_sqlStatementStream.h151
-rw-r--r--storage/ibmdb2i/db2i_validatedPointer.h162
-rw-r--r--storage/ibmdb2i/ha_ibmdb2i.cc3359
-rw-r--r--storage/ibmdb2i/ha_ibmdb2i.h822
-rw-r--r--storage/ibmdb2i/plug.in12
-rw-r--r--storage/myisam/ft_nlq_search.c2
-rw-r--r--storage/myisam/mi_create.c4
-rw-r--r--storage/myisammrg/myrg_open.c2
-rw-r--r--tests/mysql_client_test.c6
172 files changed, 771 insertions, 42247 deletions
diff --git a/.bzrignore b/.bzrignore
index e1e2083e2d2..3d27c001e2b 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -9,15 +9,19 @@
*.core
*.d
*.da
+*.dll
*.exe
+*.exp
*.gcda
*.gcno
*.gcov
*.idb
+*.ilk
*.la
*.lai
*.lib
*.lo
+*.manifest
*.map
*.o
*.obj
@@ -87,6 +91,7 @@ BitKeeper/tmp/*
BitKeeper/tmp/bkr3sAHD
BitKeeper/tmp/gone
CMakeFiles/*
+CMakeFiles
COPYING
COPYING.LIB
Docs/#manual.texi#
@@ -146,6 +151,7 @@ Makefile
Makefile.in
Makefile.in'
PENDING/*
+scripts/scripts
TAGS
VC++Files/client/mysql_amd64.dsp
ac_available_languages_fragment
@@ -1968,6 +1974,7 @@ sql-bench/test-transactions
sql-bench/test-wisconsin
sql/*.cpp
sql/*.ds?
+sql/*.def
sql/*.vcproj
sql/.deps/client.Po
sql/.deps/derror.Po
@@ -2100,6 +2107,7 @@ sql/.libs/udf_example.lai
sql/.libs/udf_example.so.0
sql/.libs/udf_example.so.0.0.0
sql/client.c
+sql/cmake_dummy.cc
sql/Doxyfile
sql/f.c
sql/gen_lex_hash
@@ -3030,6 +3038,7 @@ vio/viotest.cpp
win/configure.data
win/vs71cache.txt
win/vs8cache.txt
+win/nmake_cache.txt
ylwrap
zlib/*.ds?
zlib/*.vcproj
diff --git a/BUILD/compile-pentium-mysqlfs-debug b/BUILD/compile-pentium-mysqlfs-debug
index c871200604e..0f457eec0bb 100755
--- a/BUILD/compile-pentium-mysqlfs-debug
+++ b/BUILD/compile-pentium-mysqlfs-debug
@@ -6,6 +6,6 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags"
extra_configs="$pentium_configs $debug_configs $static_link"
-extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server --without-pstack"
+extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server"
. "$path/FINISH.sh"
diff --git a/Makefile.am b/Makefile.am
index 4ce753ad8aa..9996d187cd4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,6 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
@readline_topdir@ sql-common scripts \
- @pstack_dir@ \
@sql_union_dirs@ unittest \
@sql_server@ @man_dirs@ tests \
netware @libmysqld_dirs@ \
@@ -32,7 +31,6 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
DIST_SUBDIRS = . include Docs zlib \
cmd-line-utils sql-common scripts \
- pstack \
strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \
vio sql man tests \
netware libmysqld \
diff --git a/README b/README
index ac92d77f8bd..71491e31a8c 100644
--- a/README
+++ b/README
@@ -1192,97 +1192,3 @@ library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
***************************************************************************
-
-%%The following software may be included in this product:
-pstack (part of GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-pstack is comprised of various .c and .h files; all begin like this:
-
-/* bucomm.h -- binutils common include file.
- Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU Binutils.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
-
-***************************************************************************
-
-%%The following software may be included in this product:
-libiberty.h (part of pstack GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-See
-http://www.koders.com/c/fid99F596804BBE22C076522B848D5575F142079064.aspx
-
-/* Function declarations for libiberty.
- Written by Cygnus Support, 1994.
-
- The libiberty library provides a number of functions which are
- missing on some operating systems. We do not declare those here,
- to avoid conflicts with the system header files on operating
- systems that do support those functions. In this file we only
- declare those functions which are specific to libiberty. */
-
-***************************************************************************
-
-%%The following software may be included in this product:
-ieee.h (part of pstack GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-See
-http://src.opensolaris.org/source/xref//sfw/usr/src/cmd/gdb/gdb-6.3/include/ieee.h
-
-
-/* IEEE Standard 695-1980 "Universal Format for Object Modules"
-header file
- Contributed by Cygnus Support. */
-
-***************************************************************************
-
-%%The following software may be included in this product:
-pstack.c (part of pstack GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-/*
- pstack.c -- asynchronous stack trace of a running process
- Copyright (c) 1999 Ross Thompson
- Author: Ross Thompson
- Critical bug fix: Tim Waugh
-*/
-
-/*
- This file is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
-*/
-
-***************************************************************************
diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c
index c669322f436..0ea8b1ca126 100644
--- a/cmd-line-utils/readline/bind.c
+++ b/cmd-line-utils/readline/bind.c
@@ -855,7 +855,7 @@ _rl_read_init_file (filename, include_level)
{
register int i;
char *buffer, *openname, *line, *end;
- size_t file_size;
+ size_t file_size = 0;
current_readline_init_file = filename;
current_readline_init_include_level = include_level;
diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4
index 5960853d7f1..b4d2f08e558 100644
--- a/config/ac-macros/maintainer.m4
+++ b/config/ac-macros/maintainer.m4
@@ -19,6 +19,7 @@ AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [
AS_IF([test "$GCC" = "yes"], [
C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror"
CXX_WARNINGS="${C_WARNINGS} -Wno-unused-parameter"
+ C_WARNINGS="${C_WARNINGS} -Wdeclaration-after-statement"
])
# Test whether the warning options work.
diff --git a/configure.in b/configure.in
index 7fd581af009..6c9c64d9c86 100644
--- a/configure.in
+++ b/configure.in
@@ -910,46 +910,6 @@ struct request_info *req;
])
AC_SUBST(WRAPLIBS)
-if test "$TARGET_LINUX" = "true"; then
- AC_ARG_WITH(pstack,
- [ --with-pstack Use the pstack backtrace library],
- [ USE_PSTACK=$withval ],
- [ USE_PSTACK=no ])
- pstack_libs=
- pstack_dir=
- if test "$USE_PSTACK" = yes -a "$TARGET_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386"
- then
- have_libiberty= have_libbfd=
- my_save_LIBS="$LIBS"
-dnl I have no idea if this is a good test - can not find docs for libiberty
- AC_CHECK_LIB([iberty], [fdmatch],
- [have_libiberty=yes
- AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])])
- LIBS="$my_save_LIBS"
-
- if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes
- then
- pstack_dir="pstack"
- pstack_libs="../pstack/libpstack.a -lbfd -liberty"
- # We must link staticly when using pstack
- with_mysqld_ldflags="-all-static"
- AC_SUBST([pstack_dir])
- AC_SUBST([pstack_libs])
- AC_DEFINE([USE_PSTACK], [1], [the pstack backtrace library])
-dnl This check isn't needed, but might be nice to give some feedback....
-dnl AC_CHECK_HEADER(libiberty.h,
-dnl have_libiberty_h=yes,
-dnl have_libiberty_h=no)
- else
- USE_PSTACK="no"
- fi
- else
- USE_PSTACK="no"
- fi
-fi
-AC_MSG_CHECKING([if we should use pstack])
-AC_MSG_RESULT([$USE_PSTACK])
-
# Check for gtty if termio.h doesn't exists
if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no"
then
@@ -1178,7 +1138,7 @@ dnl Is this the right match for DEC OSF on alpha?
sql/Makefile.in)
# Use gen_lex_hash.linux instead of gen_lex_hash
# Add library dependencies to mysqld_DEPENDENCIES
- lib_DEPENDENCIES="\$(pstack_libs) \$(openssl_libs) \$(yassl_libs)"
+ lib_DEPENDENCIES="\$(openssl_libs) \$(yassl_libs)"
cat > $filesed << EOF
s,\(\./gen_lex_hash\)\$(EXEEXT),\1.linux,
s%\(mysqld_DEPENDENCIES = \)%\1$lib_DEPENDENCIES %
@@ -2880,9 +2840,6 @@ esac
AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS)
# Output results
-if test -d "$srcdir/pstack" ; then
- AC_CONFIG_FILES(pstack/Makefile pstack/aout/Makefile)
-fi
if test -d "$srcdir/cmd-line-utils/readline" ; then
AC_CONFIG_FILES(cmd-line-utils/readline/Makefile)
fi
diff --git a/include/m_string.h b/include/m_string.h
index 3e5cd063b7b..c963e605501 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -73,7 +73,9 @@ extern "C" {
extern void *(*my_str_malloc)(size_t);
extern void (*my_str_free)(void *);
-#if defined(HAVE_STPCPY)
+#if defined(HAVE_STPCPY) && MY_GNUC_PREREQ(3, 4)
+#define strmov(A,B) __builtin_stpcpy((A),(B))
+#elif defined(HAVE_STPCPY)
#define strmov(A,B) stpcpy((A),(B))
#ifndef stpcpy
extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
diff --git a/include/my_compiler.h b/include/my_compiler.h
index c7d334999d0..5f898621159 100644
--- a/include/my_compiler.h
+++ b/include/my_compiler.h
@@ -76,6 +76,11 @@
/**
Generic (compiler-independent) features.
*/
+
+#ifndef MY_GNUC_PREREQ
+# define MY_GNUC_PREREQ(maj, min) (0)
+#endif
+
#ifndef MY_ALIGNOF
# ifdef __cplusplus
template<typename type> struct my_alignof_helper { char m1; type m2; };
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index 4a7fd3ef63c..a7d6e610918 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -20,7 +20,6 @@
/* Things we don't need in the embedded version of MySQL */
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
-#undef HAVE_PSTACK /* No stacktrace */
#undef HAVE_OPENSSL
#undef HAVE_SMEM /* No shared memory */
#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 8c612b6894e..deb7cd10d2a 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -131,8 +131,8 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)),
mysql_port = MYSQL_PORT;
#ifndef MSDOS
{
- struct servent *serv_ptr;
- char *env;
+ char *env;
+ struct servent *serv_ptr __attribute__((unused));
/*
if builder specifically requested a default port, use that
diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly
index e69de29bb2d..5865864f4cd 100644
--- a/mysql-test/collections/default.weekly
+++ b/mysql-test/collections/default.weekly
@@ -0,0 +1,2 @@
+perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st
+perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb large_tests.alter_table rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big
diff --git a/mysql-test/collections/mysql-5.1-bugteam.daily b/mysql-test/collections/mysql-5.1-bugteam.daily
new file mode 100644
index 00000000000..0503bd49f73
--- /dev/null
+++ b/mysql-test/collections/mysql-5.1-bugteam.daily
@@ -0,0 +1,5 @@
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental
diff --git a/mysql-test/collections/mysql-5.1-bugteam.push b/mysql-test/collections/mysql-5.1-bugteam.push
new file mode 100644
index 00000000000..d01b98eb87f
--- /dev/null
+++ b/mysql-test/collections/mysql-5.1-bugteam.push
@@ -0,0 +1,4 @@
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --suite=main --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --suite=main --embedded --experimental=collections/default.experimental --skip-ndb
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index b55e91de14a..d57ddb17622 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -170,8 +170,6 @@ sub collect_test_cases ($$$) {
if ( $opt_reorder && !$quick_collect)
{
# Reorder the test cases in an order that will make them faster to run
- my %sort_criteria;
-
# Make a mapping of test name to a string that represents how that test
# should be sorted among the other tests. Put the most important criterion
# first, then a sub-criterion, then sub-sub-criterion, etc.
@@ -183,24 +181,31 @@ sub collect_test_cases ($$$) {
# Append the criteria for sorting, in order of importance.
#
push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "A" : "B"));
+ push(@criteria, $tinfo->{template_path});
# Group test with equal options together.
# Ending with "~" makes empty sort later than filled
my $opts= $tinfo->{'master_opt'} ? $tinfo->{'master_opt'} : [];
push(@criteria, join("!", sort @{$opts}) . "~");
+ # Add slave opts if any
+ if ($tinfo->{'slave_opt'})
+ {
+ push(@criteria, join("!", sort @{$tinfo->{'slave_opt'}}));
+ }
+ # This sorts tests with force-restart *before* identical tests
+ push(@criteria, $tinfo->{force_restart} ? "force-restart" : "no-restart");
- $sort_criteria{$tinfo->{name}} = join(" ", @criteria);
+ $tinfo->{criteria}= join(" ", @criteria);
}
- @$cases = sort {
- $sort_criteria{$a->{'name'}} . $a->{'name'} cmp
- $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases;
+ @$cases = sort {$a->{criteria} cmp $b->{criteria}; } @$cases;
# For debugging the sort-order
# foreach my $tinfo (@$cases)
# {
- # print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n");
+ # my $tname= $tinfo->{name} . ' ' . $tinfo->{combination};
+ # my $crit= $tinfo->{criteria};
+ # print("$tname\n\t$crit\n");
# }
-
}
if (defined $print_testcases){
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 22d0071c89d..22c60cf1997 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -663,22 +663,40 @@ sub run_test_server ($$$) {
next;
}
- # Prefer same configuration, or just use next if --noreorder
- if (!$opt_reorder or (defined $result and
- $result->{template_path} eq $t->{template_path}))
- {
- #mtr_report("Test uses same config => good match");
- # Test uses same config => good match
- $next= splice(@$tests, $i, 1);
- last;
- }
-
# Second best choice is the first that does not fulfill
# any of the above conditions
if (!defined $second_best){
#mtr_report("Setting second_best to $i");
$second_best= $i;
}
+
+ # Smart allocation of next test within this thread.
+
+ if ($opt_reorder and $opt_parallel > 1 and defined $result)
+ {
+ my $wid= $result->{worker};
+ # Reserved for other thread, try next
+ next if (defined $t->{reserved} and $t->{reserved} != $wid);
+ if (! defined $t->{reserved})
+ {
+ # Force-restart not relevant when comparing *next* test
+ $t->{criteria} =~ s/force-restart$/no-restart/;
+ my $criteria= $t->{criteria};
+ # Reserve similar tests for this worker, but not too many
+ my $maxres= (@$tests - $i) / $opt_parallel + 1;
+ for (my $j= $i+1; $j <= $i + $maxres; $j++)
+ {
+ my $tt= $tests->[$j];
+ last unless defined $tt;
+ last if $tt->{criteria} ne $criteria;
+ $tt->{reserved}= $wid;
+ }
+ }
+ }
+
+ # At this point we have found next suitable test
+ $next= splice(@$tests, $i, 1);
+ last;
}
# Use second best choice if no other test has been found
@@ -687,10 +705,12 @@ sub run_test_server ($$$) {
mtr_error("Internal error, second best too large($second_best)")
if $second_best > $#$tests;
$next= splice(@$tests, $second_best, 1);
+ delete $next->{reserved};
}
if ($next) {
- #$next->print_test();
+ # We don't need this any more
+ delete $next->{criteria};
$next->write_test($sock, 'TESTCASE');
$running{$next->key()}= $next;
$num_ndb_tests++ if ($next->{ndb_test});
@@ -773,6 +793,11 @@ sub run_worker ($) {
delete($test->{'comment'});
delete($test->{'logfile'});
+ # A sanity check. Should this happen often we need to look at it.
+ if (defined $test->{reserved} && $test->{reserved} != $thread_num) {
+ my $tres= $test->{reserved};
+ mtr_warning("Test reserved for w$tres picked up by w$thread_num");
+ }
$test->{worker} = $thread_num if $opt_parallel > 1;
run_testcase($test);
@@ -4582,17 +4607,6 @@ sub server_need_restart {
}
}
- # Temporary re-enable the "always restart slave" hack
- # this should be removed asap, but will require that each rpl
- # testcase cleanup better after itself - ie. stop and reset
- # replication
- # Use the "#!use-slave-opt" marker to detect that this is a "slave"
- # server
- if ( $server->option("#!use-slave-opt") ){
- mtr_verbose_restart($server, "Always restart slave(s)");
- return 1;
- }
-
my $is_mysqld= grep ($server eq $_, mysqlds());
if ($is_mysqld)
{
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 4ff4cfa586b..48e837f180f 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1343,4 +1343,18 @@ SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
1
1
DROP TABLE t1;
+#
+# Bug #52160: crash and inconsistent results when grouping
+# by a function and column
+#
+CREATE TABLE t1(a CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES (''),('');
+SELECT COUNT(*) FROM t1 GROUP BY TIME_TO_SEC(a);
+COUNT(*)
+2
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+Warning 1292 Truncated incorrect time value: ''
+Warning 1292 Truncated incorrect time value: ''
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index f8321520880..fcde09db7c5 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -899,6 +899,16 @@ TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - KEY', f1,f2,f3,SLEEP(1.1) FROM t1
TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - PK', f1,f2,f3,SLEEP(1.1) FROM t1 WHERE f1=2
DROP TABLE t1;
TRUNCATE TABLE mysql.slow_log;
+use mysql;
+drop table if exists renamed_general_log;
+drop table if exists renamed_slow_log;
+RENAME TABLE general_log TO renamed_general_log;
+ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log'
+RENAME TABLE slow_log TO renamed_slow_log;
+ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'slow_log'
+use test;
+flush tables with read lock;
+unlock tables;
SET @@session.long_query_time= @old_long_query_time;
SET @@global.log_output= @old_log_output;
SET @@global.slow_query_log= @old_slow_query_log;
diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result
index 2374b433fba..507c73c2683 100644
--- a/mysql-test/r/sp-bugs.result
+++ b/mysql-test/r/sp-bugs.result
@@ -73,4 +73,40 @@ CALL p1 ();
ERROR HY000: Trigger does not exist
DROP TABLE t1;
DROP PROCEDURE p1;
+#
+# Bug#54375: Error in stored procedure leaves connection
+# in different default schema
+#
+SET @@SQL_MODE = 'STRICT_ALL_TABLES';
+DROP DATABASE IF EXISTS db1;
+CREATE DATABASE db1;
+USE db1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 int NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1 (
+some_value int
+)
+RETURNS smallint
+DETERMINISTIC
+BEGIN
+INSERT INTO t1 SET c1 = some_value;
+RETURN(LAST_INSERT_ID());
+END$$
+DROP DATABASE IF EXISTS db2;
+CREATE DATABASE db2;
+USE db2;
+SELECT DATABASE();
+DATABASE()
+db2
+SELECT db1.f1(1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+SELECT DATABASE();
+DATABASE()
+db2
+USE test;
+DROP FUNCTION db1.f1;
+DROP TABLE db1.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
End of 5.1 tests
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index 08c30d884fd..e6fd49b4247 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -974,3 +974,14 @@ ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967
explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
End of 5.0 tests
+# Bug #52160: crash and inconsistent results when grouping
+# by a function and column
+CREATE FUNCTION f1() RETURNS TINYBLOB RETURN 1;
+CREATE TABLE t1(a CHAR(1));
+INSERT INTO t1 VALUES ('0'), ('0');
+SELECT COUNT(*) FROM t1 GROUP BY f1(), a;
+COUNT(*)
+2
+DROP FUNCTION f1;
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result
index 960fc6d22f4..71b32393d82 100644
--- a/mysql-test/r/variables-big.result
+++ b/mysql-test/r/variables-big.result
@@ -1,20 +1,20 @@
SET SESSION transaction_prealloc_size=1024*1024*1024*1;
SHOW PROCESSLIST;
Id User Host db Command Time State Info
-<Id> root localhost test Query <Time> NULL SHOW PROCESSLIST
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
SET SESSION transaction_prealloc_size=1024*1024*1024*2;
SHOW PROCESSLIST;
Id User Host db Command Time State Info
-<Id> root localhost test Query <Time> NULL SHOW PROCESSLIST
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
SET SESSION transaction_prealloc_size=1024*1024*1024*3;
SHOW PROCESSLIST;
Id User Host db Command Time State Info
-<Id> root localhost test Query <Time> NULL SHOW PROCESSLIST
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
SET SESSION transaction_prealloc_size=1024*1024*1024*4;
SHOW PROCESSLIST;
Id User Host db Command Time State Info
-<Id> root localhost test Query <Time> NULL SHOW PROCESSLIST
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
SET SESSION transaction_prealloc_size=1024*1024*1024*5;
SHOW PROCESSLIST;
Id User Host db Command Time State Info
-<Id> root localhost test Query <Time> NULL SHOW PROCESSLIST
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
diff --git a/mysql-test/suite/binlog/t/binlog_index-master.opt b/mysql-test/suite/binlog/t/binlog_index-master.opt
new file mode 100644
index 00000000000..cef79bc8585
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_index-master.opt
@@ -0,0 +1 @@
+--force-restart
diff --git a/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt b/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt
index ad2c6a647b5..377e2114039 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt
+++ b/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt
@@ -1 +1,2 @@
-O max_binlog_size=4096
+--force-restart
diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
index e2cfcb299cf..2a1187d3fe4 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
+++ b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
@@ -1 +1,2 @@
--binlog-do-db=b42829
+--force-restart
diff --git a/mysql-test/suite/ibmdb2i/include/have_i54.inc b/mysql-test/suite/ibmdb2i/include/have_i54.inc
deleted file mode 100755
index 7054e196153..00000000000
--- a/mysql-test/suite/ibmdb2i/include/have_i54.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-# Check for IBM i 6.1 or later
---disable_query_log
-system uname -rv > $MYSQLTEST_VARDIR/tmp/version;
---disable_warnings
-drop table if exists uname_vr;
---enable_warnings
-create temporary table uname_vr (r int, v int);
---disable_warnings
-eval LOAD DATA INFILE "$MYSQLTEST_VARDIR/tmp/version" into table uname_vr fields terminated by ' ';
---enable_warnings
-let $ok = `select count(*) from uname_vr where v = 5 and r = 4`;
-drop table uname_vr;
-remove_file $MYSQLTEST_VARDIR/tmp/version;
---enable_query_log
-if (!$ok)
-{
- skip "Need IBM i 5.4 or later";
-}
-
-
diff --git a/mysql-test/suite/ibmdb2i/include/have_i61.inc b/mysql-test/suite/ibmdb2i/include/have_i61.inc
deleted file mode 100644
index 84b9a17c1d8..00000000000
--- a/mysql-test/suite/ibmdb2i/include/have_i61.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-# Check for IBM i 6.1 or later
---disable_query_log
-system uname -rv > $MYSQLTEST_VARDIR/tmp/version;
---disable_warnings
-drop table if exists uname_vr;
---enable_warnings
-create temporary table uname_vr (r int, v int);
---disable_warnings
-eval LOAD DATA INFILE "$MYSQLTEST_VARDIR/tmp/version" into table uname_vr fields terminated by ' ';
---enable_warnings
-let $ok = `select count(*) from uname_vr where v > 5`;
-drop table uname_vr;
-remove_file $MYSQLTEST_VARDIR/tmp/version;
---enable_query_log
-if (!$ok)
-{
- skip "Need IBM i 6.1 or later";
-}
-
-
diff --git a/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc b/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc
deleted file mode 100644
index f3ef0b4f1ac..00000000000
--- a/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc
+++ /dev/null
@@ -1,6 +0,0 @@
-if (!`SELECT count(*) FROM information_schema.engines WHERE
- (support = 'YES' OR support = 'DEFAULT') AND
- engine = 'ibmdb2i'`)
-{
- skip Need ibmdb2i engine;
-}
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result
deleted file mode 100644
index ddf92db6bca..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result
+++ /dev/null
@@ -1,11 +0,0 @@
-create schema `A12345_@$#`;
-create table `A12345_@$#`.t1 (i int) engine=ibmdb2i;
-show create table `A12345_@$#`.t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `i` int(11) DEFAULT NULL
-) ENGINE=IBMDB2I DEFAULT CHARSET=latin1
-select * from `A12345_@$#`.t1;
-i
-drop table `A12345_@$#`.t1;
-drop schema `A12345_@$#`;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result
deleted file mode 100644
index 10a3070fcc4..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result
+++ /dev/null
@@ -1,4 +0,0 @@
-create table t1 (c char(10) collate utf8_swedish_ci, index(c)) engine=ibmdb2i;
-drop table t1;
-create table t1 (c char(10) collate ucs2_swedish_ci, index(c)) engine=ibmdb2i;
-drop table t1;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result
deleted file mode 100755
index 8276b401073..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result
+++ /dev/null
@@ -1,4 +0,0 @@
-create table t1 (c char(1) character set armscii8) engine=ibmdb2i;
-ERROR HY000: Can't create table 'test.t1' (errno: 2504)
-create table t1 (c char(1) character set eucjpms ) engine=ibmdb2i;
-ERROR HY000: Can't create table 'test.t1' (errno: 2504)
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result
deleted file mode 100755
index 311e800e1b0..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result
+++ /dev/null
@@ -1,18 +0,0 @@
-create table ABC (i int) engine=ibmdb2i;
-drop table ABC;
-create table `1234567890ABC` (i int) engine=ibmdb2i;
-drop table `1234567890ABC`;
-create table `!@#$%` (i int) engine=ibmdb2i;
-drop table `!@#$%`;
-create table `ABCD#########` (i int) engine=ibmdb2i;
-drop table `ABCD#########`;
-create table `_` (i int) engine=ibmdb2i;
-drop table `_`;
-create table `abc##def` (i int) engine=ibmdb2i;
-drop table `abc##def`;
-set names utf8;
-create table İ (s1 int) engine=ibmdb2i;
-drop table İ;
-create table İİ (s1 int) engine=ibmdb2i;
-drop table İİ;
-set names latin1;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result
deleted file mode 100644
index 916e1d93ee5..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result
+++ /dev/null
@@ -1,33 +0,0 @@
-drop table if exists t1;
-create table t1 (c char(10), index(c)) collate ucs2_czech_ci engine=ibmdb2i;
-insert into t1 values ("ch"),("h"),("i");
-select * from t1 order by c;
-c
-h
-ch
-i
-drop table t1;
-create table t1 (c char(10), index(c)) collate utf8_czech_ci engine=ibmdb2i;
-insert into t1 values ("ch"),("h"),("i");
-select * from t1 order by c;
-c
-h
-ch
-i
-drop table t1;
-create table t1 (c char(10), index(c)) collate ucs2_danish_ci engine=ibmdb2i;
-insert into t1 values("abc"),("abcd"),("aaaa");
-select c from t1 order by c;
-c
-abc
-abcd
-aaaa
-drop table t1;
-create table t1 (c char(10), index(c)) collate utf8_danish_ci engine=ibmdb2i;
-insert into t1 values("abc"),("abcd"),("aaaa");
-select c from t1 order by c;
-c
-abc
-abcd
-aaaa
-drop table t1;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result
deleted file mode 100644
index 2392b746877..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result
+++ /dev/null
@@ -1,7 +0,0 @@
-drop table if exists t1;
-create table t1 (c char(10), index(c)) charset macce engine=ibmdb2i;
-insert into t1 values ("test");
-select * from t1 order by c;
-c
-test
-drop table t1;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result
deleted file mode 100644
index b9f4dcfc656..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result
+++ /dev/null
@@ -1,20 +0,0 @@
-set ibmdb2i_create_index_option=1;
-drop schema if exists test1;
-create schema test1;
-use test1;
-CREATE TABLE t1 (f int primary key, index(f)) engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (f char(10) collate utf8_bin primary key, index(f)) engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, index(f)) engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, i int, index i(i,f)) engine=ibmdb2i;
-drop table t1;
-create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i;
-select * from fd;
-SQSSEQ
-*HEX
-*HEX
-*HEX
-*HEX
-drop table fd;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result
deleted file mode 100644
index d5bfc2579fd..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result
+++ /dev/null
@@ -1,9 +0,0 @@
-create table ABC (i int) engine=ibmdb2i;
-insert into ABC values(1);
-create table abc (i int) engine=ibmdb2i;
-insert into abc values (2);
-select * from ABC;
-i
-1
-drop table ABC;
-drop table abc;
diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result
deleted file mode 100644
index 4f7d71cab2d..00000000000
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result
+++ /dev/null
@@ -1,1204 +0,0 @@
-drop table if exists t1, ffd, fd;
-CREATE TABLE t1 (armscii8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate armscii8_bin engine=ibmdb2i;
-CREATE TABLE t1 (armscii8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate armscii8_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (ascii_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ascii_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (ascii_bin char(10) primary key) collate ascii_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ascii_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ascii_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (ascii_general_ci char(10) primary key) collate ascii_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (big5_bin integer, c char(10), v varchar(20), index(c), index(v)) collate big5_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (big5_bin char(10) primary key) collate big5_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (big5_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate big5_chinese_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (big5_chinese_ci char(10) primary key) collate big5_chinese_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1250_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1250_bin char(10) primary key) collate cp1250_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1250_croatian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_croatian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1250_croatian_ci char(10) primary key) collate cp1250_croatian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1250_czech_cs integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_czech_cs engine=ibmdb2i;
-CREATE TABLE t1 (cp1250_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1250_general_ci char(10) primary key) collate cp1250_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1250_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_polish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1250_polish_ci char(10) primary key) collate cp1250_polish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1251_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1251_bin char(10) primary key) collate cp1251_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1251_bulgarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_bulgarian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1251_bulgarian_ci char(10) primary key) collate cp1251_bulgarian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1251_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1251_general_ci char(10) primary key) collate cp1251_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1251_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_general_cs engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1251_general_cs char(10) primary key) collate cp1251_general_cs engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1251_ukrainian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_ukrainian_ci engine=ibmdb2i;
-CREATE TABLE t1 (cp1256_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1256_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1256_bin char(10) primary key) collate cp1256_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1256_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1256_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp1256_general_ci char(10) primary key) collate cp1256_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp1257_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_bin engine=ibmdb2i;
-CREATE TABLE t1 (cp1257_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (cp1257_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_lithuanian_ci engine=ibmdb2i;
-CREATE TABLE t1 (cp850_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp850_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp850_bin char(10) primary key) collate cp850_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp850_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp850_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp850_general_ci char(10) primary key) collate cp850_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp852_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp852_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp852_bin char(10) primary key) collate cp852_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp852_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp852_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (cp852_general_ci char(10) primary key) collate cp852_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp866_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp866_bin engine=ibmdb2i;
-CREATE TABLE t1 (cp866_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp866_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (cp932_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp932_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (cp932_bin char(10) primary key) collate cp932_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (cp932_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp932_japanese_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (cp932_japanese_ci char(10) primary key) collate cp932_japanese_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (dec8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate dec8_bin engine=ibmdb2i;
-CREATE TABLE t1 (dec8_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate dec8_swedish_ci engine=ibmdb2i;
-CREATE TABLE t1 (eucjpms_bin integer, c char(10), v varchar(20), index(c), index(v)) collate eucjpms_bin engine=ibmdb2i;
-CREATE TABLE t1 (eucjpms_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate eucjpms_japanese_ci engine=ibmdb2i;
-CREATE TABLE t1 (euckr_bin integer, c char(10), v varchar(20), index(c), index(v)) collate euckr_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (euckr_bin char(10) primary key) collate euckr_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (euckr_korean_ci integer, c char(10), v varchar(20), index(c), index(v)) collate euckr_korean_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (euckr_korean_ci char(10) primary key) collate euckr_korean_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (gb2312_bin integer, c char(10), v varchar(20), index(c), index(v)) collate gb2312_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (gb2312_bin char(10) primary key) collate gb2312_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (gb2312_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate gb2312_chinese_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (gb2312_chinese_ci char(10) primary key) collate gb2312_chinese_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (gbk_bin integer, c char(10), v varchar(20), index(c), index(v)) collate gbk_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (gbk_bin char(10) primary key) collate gbk_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (gbk_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate gbk_chinese_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (gbk_chinese_ci char(10) primary key) collate gbk_chinese_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (geostd8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate geostd8_bin engine=ibmdb2i;
-CREATE TABLE t1 (geostd8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate geostd8_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (greek_bin integer, c char(10), v varchar(20), index(c), index(v)) collate greek_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (greek_bin char(10) primary key) collate greek_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (greek_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate greek_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (greek_general_ci char(10) primary key) collate greek_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (hebrew_bin integer, c char(10), v varchar(20), index(c), index(v)) collate hebrew_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (hebrew_bin char(10) primary key) collate hebrew_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (hebrew_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate hebrew_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (hebrew_general_ci char(10) primary key) collate hebrew_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (hp8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate hp8_bin engine=ibmdb2i;
-CREATE TABLE t1 (hp8_english_ci integer, c char(10), v varchar(20), index(c), index(v)) collate hp8_english_ci engine=ibmdb2i;
-CREATE TABLE t1 (keybcs2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate keybcs2_bin engine=ibmdb2i;
-CREATE TABLE t1 (keybcs2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate keybcs2_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (koi8r_bin integer, c char(10), v varchar(20), index(c), index(v)) collate koi8r_bin engine=ibmdb2i;
-CREATE TABLE t1 (koi8r_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate koi8r_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (koi8u_bin integer, c char(10), v varchar(20), index(c), index(v)) collate koi8u_bin engine=ibmdb2i;
-CREATE TABLE t1 (koi8u_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate koi8u_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (latin1_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_bin char(10) primary key) collate latin1_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin1_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_danish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_danish_ci char(10) primary key) collate latin1_danish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin1_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_general_ci char(10) primary key) collate latin1_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin1_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_general_cs engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_general_cs char(10) primary key) collate latin1_general_cs engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin1_german1_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_german1_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_german1_ci char(10) primary key) collate latin1_german1_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin1_german2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_german2_ci engine=ibmdb2i;
-CREATE TABLE t1 (latin1_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_spanish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_spanish_ci char(10) primary key) collate latin1_spanish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin1_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_swedish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin1_swedish_ci char(10) primary key) collate latin1_swedish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin2_bin char(10) primary key) collate latin2_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin2_croatian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_croatian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin2_croatian_ci char(10) primary key) collate latin2_croatian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin2_czech_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_czech_cs engine=ibmdb2i;
-CREATE TABLE t1 (latin2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin2_general_ci char(10) primary key) collate latin2_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin2_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_hungarian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin2_hungarian_ci char(10) primary key) collate latin2_hungarian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin5_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin5_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin5_bin char(10) primary key) collate latin5_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin5_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin5_turkish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (latin5_turkish_ci char(10) primary key) collate latin5_turkish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (latin7_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_bin engine=ibmdb2i;
-CREATE TABLE t1 (latin7_estonian_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_estonian_cs engine=ibmdb2i;
-CREATE TABLE t1 (latin7_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (latin7_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_general_cs engine=ibmdb2i;
-CREATE TABLE t1 (macce_bin integer, c char(10), v varchar(20), index(c), index(v)) collate macce_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (macce_bin char(10) primary key) collate macce_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (macce_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate macce_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (macce_general_ci char(10) primary key) collate macce_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (macroman_bin integer, c char(10), v varchar(20), index(c), index(v)) collate macroman_bin engine=ibmdb2i;
-CREATE TABLE t1 (macroman_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate macroman_general_ci engine=ibmdb2i;
-CREATE TABLE t1 (sjis_bin integer, c char(10), v varchar(20), index(c), index(v)) collate sjis_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (sjis_bin char(10) primary key) collate sjis_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (sjis_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate sjis_japanese_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (sjis_japanese_ci char(10) primary key) collate sjis_japanese_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (swe7_bin integer, c char(10), v varchar(20), index(c), index(v)) collate swe7_bin engine=ibmdb2i;
-CREATE TABLE t1 (swe7_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate swe7_swedish_ci engine=ibmdb2i;
-CREATE TABLE t1 (tis620_bin integer, c char(10), v varchar(20), index(c), index(v)) collate tis620_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (tis620_bin char(10) primary key) collate tis620_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (tis620_thai_ci integer, c char(10), v varchar(20), index(c), index(v)) collate tis620_thai_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 11 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 23 NULL 6 Using where
-drop table t1;
-create table t1 (tis620_thai_ci char(10) primary key) collate tis620_thai_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_bin char(10) primary key) collate ucs2_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_czech_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_czech_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_czech_ci char(10) primary key) collate ucs2_czech_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_danish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_danish_ci char(10) primary key) collate ucs2_danish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_esperanto_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_esperanto_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_esperanto_ci char(10) primary key) collate ucs2_esperanto_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_estonian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_estonian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_estonian_ci char(10) primary key) collate ucs2_estonian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_general_ci char(10) primary key) collate ucs2_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_hungarian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_hungarian_ci char(10) primary key) collate ucs2_hungarian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_icelandic_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_icelandic_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_icelandic_ci char(10) primary key) collate ucs2_icelandic_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_latvian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_latvian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_latvian_ci char(10) primary key) collate ucs2_latvian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_lithuanian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_lithuanian_ci char(10) primary key) collate ucs2_lithuanian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_persian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_persian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_persian_ci char(10) primary key) collate ucs2_persian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_polish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_polish_ci char(10) primary key) collate ucs2_polish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_romanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_romanian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_romanian_ci char(10) primary key) collate ucs2_romanian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_roman_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_roman_ci engine=ibmdb2i;
-CREATE TABLE t1 (ucs2_slovak_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_slovak_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_slovak_ci char(10) primary key) collate ucs2_slovak_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_slovenian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_slovenian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_slovenian_ci char(10) primary key) collate ucs2_slovenian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_spanish2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_spanish2_ci engine=ibmdb2i;
-CREATE TABLE t1 (ucs2_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_spanish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_spanish_ci char(10) primary key) collate ucs2_spanish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_swedish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_swedish_ci char(10) primary key) collate ucs2_swedish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_turkish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_turkish_ci char(10) primary key) collate ucs2_turkish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ucs2_unicode_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_unicode_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 21 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 43 NULL 6 Using where
-drop table t1;
-create table t1 (ucs2_unicode_ci char(10) primary key) collate ucs2_unicode_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ujis_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ujis_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (ujis_bin char(10) primary key) collate ujis_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (ujis_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ujis_japanese_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (ujis_japanese_ci char(10) primary key) collate ujis_japanese_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_bin engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_bin char(10) primary key) collate utf8_bin engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_czech_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_czech_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_czech_ci char(10) primary key) collate utf8_czech_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_danish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_danish_ci char(10) primary key) collate utf8_danish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_esperanto_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_esperanto_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_esperanto_ci char(10) primary key) collate utf8_esperanto_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_estonian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_estonian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_estonian_ci char(10) primary key) collate utf8_estonian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_general_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_general_ci char(10) primary key) collate utf8_general_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_hungarian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_hungarian_ci char(10) primary key) collate utf8_hungarian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_icelandic_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_icelandic_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_icelandic_ci char(10) primary key) collate utf8_icelandic_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_latvian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_latvian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_latvian_ci char(10) primary key) collate utf8_latvian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_lithuanian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_lithuanian_ci char(10) primary key) collate utf8_lithuanian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_persian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_persian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_persian_ci char(10) primary key) collate utf8_persian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_polish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_polish_ci char(10) primary key) collate utf8_polish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_romanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_romanian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_romanian_ci char(10) primary key) collate utf8_romanian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_roman_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_roman_ci engine=ibmdb2i;
-CREATE TABLE t1 (utf8_slovak_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_slovak_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_slovak_ci char(10) primary key) collate utf8_slovak_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_slovenian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_slovenian_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_slovenian_ci char(10) primary key) collate utf8_slovenian_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_spanish2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_spanish2_ci engine=ibmdb2i;
-CREATE TABLE t1 (utf8_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_spanish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_spanish_ci char(10) primary key) collate utf8_spanish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_swedish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_swedish_ci char(10) primary key) collate utf8_swedish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_turkish_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_turkish_ci char(10) primary key) collate utf8_turkish_ci engine=ibmdb2i;
-drop table t1;
-CREATE TABLE t1 (utf8_unicode_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_unicode_ci engine=ibmdb2i;
-insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
-insert into t1 select * from t1;
-explain select c,v from t1 force index(c) where c like "ab%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 31 NULL 6 Using where
-explain select c,v from t1 force index(v) where v like "de%";
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 63 NULL 6 Using where
-drop table t1;
-create table t1 (utf8_unicode_ci char(10) primary key) collate utf8_unicode_ci engine=ibmdb2i;
-drop table t1;
-create table ffd (WHCHD1 CHAR(20), WHCSID decimal(5,0)) engine=ibmdb2i;
-create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i;
-create temporary table intermed (row integer key auto_increment, cs char(30), ccsid integer);
-insert into intermed (cs, ccsid) select * from ffd;
-create temporary table intermed2 (row integer key auto_increment, srtseq char(10));
-insert into intermed2 (srtseq) select * from fd;
-select ccsid, cs, srtseq from intermed inner join intermed2 on intermed.row = intermed2.row;
-ccsid cs srtseq
-500 "ascii_bin" QBLA101F4U
-500 "ascii_general_ci" QALA101F4S
-1200 "big5_bin" QBCHT04B0U
-1200 "big5_chinese_ci" QACHT04B0S
-1153 "cp1250_bin" QELA20481U
-1153 "cp1250_croatian_ci" QALA20481S
-1153 "cp1250_general_ci" QCLA20481S
-1153 "cp1250_polish_ci" QDLA20481S
-1025 "cp1251_bin" QCCYR0401U
-1025 "cp1251_bulgarian_ci QACYR0401S
-1025 "cp1251_general_ci" QBCYR0401S
-1025 "cp1251_general_cs" QBCYR0401U
-420 "cp1256_bin" QBARA01A4U
-420 "cp1256_general_ci" QAARA01A4S
-500 "cp850_bin" QDLA101F4U
-500 "cp850_general_ci" QCLA101F4S
-870 "cp852_bin" QBLA20366U
-870 "cp852_general_ci" QALA20366S
-1200 "cp932_bin" QBJPN04B0U
-1200 "cp932_japanese_ci" QAJPN04B0S
-1200 "euckr_bin" QBKOR04B0U
-1200 "euckr_korean_ci" QAKOR04B0S
-1200 "gb2312_bin" QBCHS04B0U
-1200 "gb2312_chinese_ci" QACHS04B0S
-1200 "gbk_bin" QDCHS04B0U
-1200 "gbk_chinese_ci" QCCHS04B0S
-875 "greek_bin" QBELL036BU
-875 "greek_general_ci" QAELL036BS
-424 "hebrew_bin" QBHEB01A8U
-424 "hebrew_general_ci" QAHEB01A8S
-1148 "latin1_bin" QFLA1047CU
-1148 "latin1_danish_ci" QALA1047CS
-1148 "latin1_general_ci" QBLA1047CS
-1148 "latin1_general_cs" QBLA1047CU
-1148 "latin1_german1_ci" QCLA1047CS
-1148 "latin1_spanish_ci" QDLA1047CS
-1148 "latin1_swedish_ci" QELA1047CS
-870 "latin2_bin" QGLA20366U
-870 "latin2_croatian_ci" QCLA20366S
-870 "latin2_general_ci" QELA20366S
-870 "latin2_hungarian_ci QFLA20366S
-1026 "latin5_bin" QBTRK0402U
-1026 "latin5_turkish_ci" QATRK0402S
-870 "macce_bin" QILA20366U
-870 "macce_general_ci" QHLA20366S
-1200 "sjis_bin" QDJPN04B0U
-1200 "sjis_japanese_ci" QCJPN04B0S
-838 "tis620_bin" QBTHA0346U
-838 "tis620_thai_ci" QATHA0346S
-13488 "ucs2_bin" *HEX
-13488 "ucs2_czech_ci" I34ACS_CZ
-13488 "ucs2_danish_ci" I34ADA_DK
-13488 "ucs2_esperanto_ci" I34AEO
-13488 "ucs2_estonian_ci" I34AET
-13488 "ucs2_general_ci" QAUCS04B0S
-13488 "ucs2_hungarian_ci" I34AHU
-13488 "ucs2_icelandic_ci" I34AIS
-13488 "ucs2_latvian_ci" I34ALV
-13488 "ucs2_lithuanian_ci" I34ALT
-13488 "ucs2_persian_ci" I34AFA
-13488 "ucs2_polish_ci" I34APL
-13488 "ucs2_romanian_ci" I34ARO
-13488 "ucs2_slovak_ci" I34ASK
-13488 "ucs2_slovenian_ci" I34ASL
-13488 "ucs2_spanish_ci" I34AES
-13488 "ucs2_swedish_ci" I34ASW
-13488 "ucs2_turkish_ci" I34ATR
-13488 "ucs2_unicode_ci" I34AEN
-1200 "ujis_bin" QFJPN04B0U
-1200 "ujis_japanese_ci" QEJPN04B0S
-1208 "utf8_bin" *HEX
-1208 "utf8_czech_ci" I34ACS_CZ
-1208 "utf8_danish_ci" I34ADA_DK
-1208 "utf8_esperanto_ci" I34AEO
-1208 "utf8_estonian_ci" I34AET
-1200 "utf8_general_ci" QAUCS04B0S
-1208 "utf8_hungarian_ci" I34AHU
-1208 "utf8_icelandic_ci" I34AIS
-1208 "utf8_latvian_ci" I34ALV
-1208 "utf8_lithuanian_ci" I34ALT
-1208 "utf8_persian_ci" I34AFA
-1208 "utf8_polish_ci" I34APL
-1208 "utf8_romanian_ci" I34ARO
-1208 "utf8_slovak_ci" I34ASK
-1208 "utf8_slovenian_ci" I34ASL
-1208 "utf8_spanish_ci" I34AES
-1208 "utf8_swedish_ci" I34ASW
-1208 "utf8_turkish_ci" I34ATR
-1208 "utf8_unicode_ci" I34AEN
-drop table ffd, fd;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test
deleted file mode 100644
index 09a7c75cfc0..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test
+++ /dev/null
@@ -1,9 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-source include/have_case_sensitive_file_system.inc;
-
-create schema `A12345_@$#`;
-create table `A12345_@$#`.t1 (i int) engine=ibmdb2i;
-show create table `A12345_@$#`.t1;
-select * from `A12345_@$#`.t1;
-drop table `A12345_@$#`.t1;
-drop schema `A12345_@$#`;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test
deleted file mode 100644
index 9b033a2298f..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test
+++ /dev/null
@@ -1,9 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-source suite/ibmdb2i/include/have_i61.inc;
-
-
-create table t1 (c char(10) collate utf8_swedish_ci, index(c)) engine=ibmdb2i;
-drop table t1;
-
-create table t1 (c char(10) collate ucs2_swedish_ci, index(c)) engine=ibmdb2i;
-drop table t1;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test
deleted file mode 100755
index ea29b5abcd4..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test
+++ /dev/null
@@ -1,8 +0,0 @@
---source suite/ibmdb2i/include/have_ibmdb2i.inc
---source suite/ibmdb2i/include/have_i54.inc
-
---error 1005
-create table t1 (c char(1) character set armscii8) engine=ibmdb2i;
-
---error 1005
-create table t1 (c char(1) character set eucjpms ) engine=ibmdb2i;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test
deleted file mode 100755
index da69b5d9148..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test
+++ /dev/null
@@ -1,28 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-
-# Test RCDFMT generation for a variety of kinds of table names
-create table ABC (i int) engine=ibmdb2i;
-drop table ABC;
-
-create table `1234567890ABC` (i int) engine=ibmdb2i;
-drop table `1234567890ABC`;
-
-create table `!@#$%` (i int) engine=ibmdb2i;
-drop table `!@#$%`;
-
-create table `ABCD#########` (i int) engine=ibmdb2i;
-drop table `ABCD#########`;
-
-create table `_` (i int) engine=ibmdb2i;
-drop table `_`;
-
-create table `abc##def` (i int) engine=ibmdb2i;
-drop table `abc##def`;
-
-set names utf8;
-create table İ (s1 int) engine=ibmdb2i;
-drop table İ;
-
-create table İİ (s1 int) engine=ibmdb2i;
-drop table İİ;
-set names latin1;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test
deleted file mode 100644
index 17b1d658975..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test
+++ /dev/null
@@ -1,26 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-source suite/ibmdb2i/include/have_i61.inc;
-
---disable_warnings
-drop table if exists t1;
---enable_warnings
-
-create table t1 (c char(10), index(c)) collate ucs2_czech_ci engine=ibmdb2i;
-insert into t1 values ("ch"),("h"),("i");
-select * from t1 order by c;
-drop table t1;
-
-create table t1 (c char(10), index(c)) collate utf8_czech_ci engine=ibmdb2i;
-insert into t1 values ("ch"),("h"),("i");
-select * from t1 order by c;
-drop table t1;
-
-create table t1 (c char(10), index(c)) collate ucs2_danish_ci engine=ibmdb2i;
-insert into t1 values("abc"),("abcd"),("aaaa");
-select c from t1 order by c;
-drop table t1;
-
-create table t1 (c char(10), index(c)) collate utf8_danish_ci engine=ibmdb2i;
-insert into t1 values("abc"),("abcd"),("aaaa");
-select c from t1 order by c;
-drop table t1;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test
deleted file mode 100644
index 93fb78ff421..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test
+++ /dev/null
@@ -1,11 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-source suite/ibmdb2i/include/have_i61.inc;
-
---disable_warnings
-drop table if exists t1;
---enable_warnings
-
-create table t1 (c char(10), index(c)) charset macce engine=ibmdb2i;
-insert into t1 values ("test");
-select * from t1 order by c;
-drop table t1;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test
deleted file mode 100644
index 695d8e90ada..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test
+++ /dev/null
@@ -1,47 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-
-# Confirm that ibmdb2i_create_index_option causes additional *HEX sorted indexes to be created for all non-binary keys.
-
-set ibmdb2i_create_index_option=1;
---disable_warnings
-drop schema if exists test1;
-create schema test1;
-use test1;
---enable_warnings
-
---disable_abort_on_error
---error 0,255
-exec system "DLTF QGPL/FDOUT" > /dev/null;
---enable_abort_on_error
-
-#No additional index because no string fields in key
-CREATE TABLE t1 (f int primary key, index(f)) engine=ibmdb2i;
---error 255
-exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
---error 255
-exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
-drop table t1;
-
-#No additional index because binary sorting
-CREATE TABLE t1 (f char(10) collate utf8_bin primary key, index(f)) engine=ibmdb2i;
---error 255
-exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
---error 255
-exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
-drop table t1;
-
-CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, index(f)) engine=ibmdb2i;
-exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
-exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
-drop table t1;
-
-CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, i int, index i(i,f)) engine=ibmdb2i;
-exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
-exec system "DSPFD FILE(\"test1\"/\"i___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
-drop table t1;
-
-
-create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i;
-system system "CPYF FROMFILE(QGPL/FDOUT) TOFILE(\"test1\"/\"fd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null;
-select * from fd;
-drop table fd;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test
deleted file mode 100644
index 615df284d8f..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test
+++ /dev/null
@@ -1,10 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-source include/have_case_sensitive_file_system.inc;
-
-create table ABC (i int) engine=ibmdb2i;
-insert into ABC values(1);
-create table abc (i int) engine=ibmdb2i;
-insert into abc values (2);
-select * from ABC;
-drop table ABC;
-drop table abc;
diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test
deleted file mode 100644
index 899f330d360..00000000000
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test
+++ /dev/null
@@ -1,44 +0,0 @@
-source suite/ibmdb2i/include/have_ibmdb2i.inc;
-source suite/ibmdb2i/include/have_i61.inc;
---disable_warnings
-drop table if exists t1, ffd, fd;
---enable_warnings
-
---disable_abort_on_error
---error 0,255
-exec system "DLTF QGPL/FFDOUT" > /dev/null;
---error 0,255
-exec system "DLTF QGPL/FDOUT" > /dev/null;
---enable_abort_on_error
-let $count= query_get_value(select count(*) from information_schema.COLLATIONS where COLLATION_NAME <> "binary", count(*),1);
-
-while ($count)
-{
- let $collation = query_get_value(select COLLATION_NAME from information_schema.COLLATIONS where COLLATION_NAME <> "binary" order by COLLATION_NAME desc, COLLATION_NAME, $count);
- error 0,1005,2504,2028;
- eval CREATE TABLE t1 ($collation integer, c char(10), v varchar(20), index(c), index(v)) collate $collation engine=ibmdb2i;
- if (!$mysql_errno)
- {
- insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb");
- insert into t1 select * from t1;
- explain select c,v from t1 force index(c) where c like "ab%";
- explain select c,v from t1 force index(v) where v like "de%";
- drop table t1;
- eval create table t1 ($collation char(10) primary key) collate $collation engine=ibmdb2i;
- system system "DSPFFD FILE(\"test\"/\"t1\") OUTPUT(*OUTFILE) OUTFILE(QGPL/FFDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
- system system "DSPFD FILE(\"test\"/\"t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null;
- drop table t1;
- }
- dec $count;
-}
-
-create table ffd (WHCHD1 CHAR(20), WHCSID decimal(5,0)) engine=ibmdb2i;
-system system "CPYF FROMFILE(QGPL/FFDOUT) TOFILE(\"test\"/\"ffd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null;
-create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i;
-system system "CPYF FROMFILE(QGPL/FDOUT) TOFILE(\"test\"/\"fd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null;
-create temporary table intermed (row integer key auto_increment, cs char(30), ccsid integer);
-insert into intermed (cs, ccsid) select * from ffd;
-create temporary table intermed2 (row integer key auto_increment, srtseq char(10));
-insert into intermed2 (srtseq) select * from fd;
-select ccsid, cs, srtseq from intermed inner join intermed2 on intermed.row = intermed2.row;
-drop table ffd, fd;
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index 65b7da143a4..6ac3e8e6302 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -2620,3 +2620,11 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2, t1;
+#
+# Test for bug #56619 - Assertion failed during
+# ALTER TABLE RENAME, DISABLE KEYS
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb;
+ALTER TABLE t1 RENAME TO t2, DISABLE KEYS;
+DROP TABLE IF EXISTS t1, t2;
diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test
index 09dc4c9f187..e99c3c27673 100644
--- a/mysql-test/suite/innodb/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test
@@ -845,3 +845,16 @@ create table t2 (fk int, key x (fk),
constraint x foreign key (FK) references t1 (PK)) engine=InnoDB;
show create table t2;
drop table t2, t1;
+
+--echo #
+--echo # Test for bug #56619 - Assertion failed during
+--echo # ALTER TABLE RENAME, DISABLE KEYS
+--echo #
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb;
+--disable_warnings
+ALTER TABLE t1 RENAME TO t2, DISABLE KEYS;
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
diff --git a/mysql-test/suite/parts/inc/partition_auto_increment.inc b/mysql-test/suite/parts/inc/partition_auto_increment.inc
index 102e57d3d04..034460d49ac 100644
--- a/mysql-test/suite/parts/inc/partition_auto_increment.inc
+++ b/mysql-test/suite/parts/inc/partition_auto_increment.inc
@@ -105,6 +105,30 @@ OPTIMIZE TABLE t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+if (!$skip_update)
+{
+eval CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+ UNIQUE KEY (a))
+ENGINE=$engine;
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+DROP TABLE t1;
+SET INSERT_ID = 1;
+}
+
-- echo # Simple test with NULL
eval CREATE TABLE t1 (
c1 INT NOT NULL AUTO_INCREMENT,
@@ -831,5 +855,30 @@ SELECT * FROM t ORDER BY c1 ASC;
DROP TABLE t;
+if (!$skip_update)
+{
+eval CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+ UNIQUE KEY (a))
+ENGINE=$engine
+PARTITION BY KEY(a) PARTITIONS 2;
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+SELECT * FROM t1;
+DROP TABLE t1;
+}
+
+
--echo ##############################################################################
}
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result
index d6ea8ba0fe4..2344f03ce3f 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result
@@ -120,6 +120,38 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`)
) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1
DROP TABLE t1;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='Blackhole';
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+DROP TABLE t1;
+SET INSERT_ID = 1;
# Simple test with NULL
CREATE TABLE t1 (
c1 INT NOT NULL AUTO_INCREMENT,
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result
index 4cd7aa57417..5fd576322d5 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result
@@ -136,6 +136,42 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
DROP TABLE t1;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='InnoDB';
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+1
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
+SET INSERT_ID = 1;
# Simple test with NULL
CREATE TABLE t1 (
c1 INT NOT NULL AUTO_INCREMENT,
@@ -1023,4 +1059,40 @@ c1 c2
2 20
127 40
DROP TABLE t;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='InnoDB'
+PARTITION BY KEY(a) PARTITIONS 2;
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+1
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result
index 1a27d1c2e52..c3a5073b029 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result
@@ -136,6 +136,42 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`)
) ENGINE=MEMORY AUTO_INCREMENT=102 DEFAULT CHARSET=latin1
DROP TABLE t1;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='Memory';
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+1
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
+SET INSERT_ID = 1;
# Simple test with NULL
CREATE TABLE t1 (
c1 INT NOT NULL AUTO_INCREMENT,
@@ -1051,4 +1087,40 @@ c1 c2
2 20
127 40
DROP TABLE t;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='Memory'
+PARTITION BY KEY(a) PARTITIONS 2;
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+1
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result
index 9885c78a921..ad440155d33 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result
@@ -136,6 +136,42 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`)
) ENGINE=MyISAM AUTO_INCREMENT=102 DEFAULT CHARSET=latin1
DROP TABLE t1;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='MyISAM';
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+1
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
+SET INSERT_ID = 1;
# Simple test with NULL
CREATE TABLE t1 (
c1 INT NOT NULL AUTO_INCREMENT,
@@ -1070,4 +1106,40 @@ c1 c2
2 20
127 40
DROP TABLE t;
+CREATE TABLE t1
+(a INT NULL AUTO_INCREMENT,
+UNIQUE KEY (a))
+ENGINE='MyISAM'
+PARTITION BY KEY(a) PARTITIONS 2;
+SET LAST_INSERT_ID = 999;
+SET INSERT_ID = 0;
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+1
+INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = 1 WHERE a IS NULL;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+UPDATE t1 SET a = NULL WHERE a = 1;
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+999
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
##############################################################################
diff --git a/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test b/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test
index e8d263e369c..002da3c8f37 100644
--- a/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test
+++ b/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test
@@ -28,6 +28,9 @@ let $do_long_tests= 1;
# The server must support partitioning.
--source include/have_partition.inc
+# This test takes long time, so only run it with the --big mtr-flag.
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# Engine specific settings and requirements
diff --git a/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test
index 8e3dde286cf..6ac1803a972 100644
--- a/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test
+++ b/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test
@@ -46,6 +46,9 @@ let $more_pk_ui_tests= 0;
# The server must support partitioning.
--source include/have_partition.inc
+# This test takes long time, so only run it with the --big mtr-flag.
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# Engine specific settings and requirements
diff --git a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test
index 76fe7eb0223..2cbe0ab77ab 100644
--- a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test
+++ b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test
@@ -46,6 +46,9 @@ let $more_pk_ui_tests= 0;
# The server must support partitioning.
--source include/have_partition.inc
+# This test takes long time, so only run it with the --big mtr-flag.
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# Engine specific settings and requirements
diff --git a/mysql-test/suite/parts/t/partition_alter4_innodb.test b/mysql-test/suite/parts/t/partition_alter4_innodb.test
index 3061e5c9e7f..1e28a2fc812 100644
--- a/mysql-test/suite/parts/t/partition_alter4_innodb.test
+++ b/mysql-test/suite/parts/t/partition_alter4_innodb.test
@@ -43,6 +43,9 @@ let $more_pk_ui_tests= 0;
# The server must support partitioning.
--source include/have_partition.inc
+# This test takes long time, so only run it with the --big mtr-flag.
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# Engine specific settings and requirements
diff --git a/mysql-test/suite/rpl/r/rpl_ignore_table.result b/mysql-test/suite/rpl/r/rpl_ignore_table.result
index e77be425270..6b845ddcac9 100644
--- a/mysql-test/suite/rpl/r/rpl_ignore_table.result
+++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result
@@ -141,3 +141,4 @@ HEX(word)
SELECT * FROM tmptbl504451f4258$1;
ERROR 42S02: Table 'test.tmptbl504451f4258$1' doesn't exist
DROP TABLE t5;
+call mtr.force_restart();
diff --git a/mysql-test/suite/rpl/t/rpl_cross_version-master.opt b/mysql-test/suite/rpl/t/rpl_cross_version-master.opt
index 0ea05290c11..2b2d357b124 100644
--- a/mysql-test/suite/rpl/t/rpl_cross_version-master.opt
+++ b/mysql-test/suite/rpl/t/rpl_cross_version-master.opt
@@ -1 +1,2 @@
--replicate-same-server-id --relay-log=slave-relay-bin --secure-file-priv=$MYSQL_TMP_DIR
+--force-restart
diff --git a/mysql-test/suite/rpl/t/rpl_current_user-master.opt b/mysql-test/suite/rpl/t/rpl_current_user-master.opt
new file mode 100644
index 00000000000..cef79bc8585
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_current_user-master.opt
@@ -0,0 +1 @@
+--force-restart
diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table.test b/mysql-test/suite/rpl/t/rpl_ignore_table.test
index 66f96e8f4e8..b5666ad6e91 100644
--- a/mysql-test/suite/rpl/t/rpl_ignore_table.test
+++ b/mysql-test/suite/rpl/t/rpl_ignore_table.test
@@ -174,3 +174,5 @@ SELECT * FROM tmptbl504451f4258$1;
connection master;
DROP TABLE t5;
sync_slave_with_master;
+
+call mtr.force_restart();
diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh
index 066f72926af..e5bb3e61d11 100644
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh
@@ -1 +1,2 @@
+rm -f $MYSQLTEST_VARDIR/std_data_master_link
ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_master_link
diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh
index 218209a2542..7a0c0bb382a 100644
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh
@@ -1 +1,2 @@
+rm -f $MYSQLTEST_VARDIR/std_data_slave_link
ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_slave_link
diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt b/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt
new file mode 100644
index 00000000000..cef79bc8585
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt
@@ -0,0 +1 @@
+--force-restart
diff --git a/mysql-test/suite/sys_vars/README b/mysql-test/suite/sys_vars/README
deleted file mode 100644
index a84f00f1f62..00000000000
--- a/mysql-test/suite/sys_vars/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Some of these tests allocate more than 4GB RAM.
-So, assure that the machine on which the suite will be executed has more than 4GB RAM.
-
diff --git a/mysql-test/suite/sys_vars/inc/timestamp_basic.inc b/mysql-test/suite/sys_vars/inc/timestamp_basic.inc
index 9ef57c97043..68ded3e5a97 100644
--- a/mysql-test/suite/sys_vars/inc/timestamp_basic.inc
+++ b/mysql-test/suite/sys_vars/inc/timestamp_basic.inc
@@ -66,10 +66,6 @@ SET @@timestamp = 0;
--echo 'Setting 0 resets timestamp to session default timestamp'
-SET @@timestamp = 123456789123456;
-SELECT @@timestamp;
-SET @@timestamp = 60*60*60*60*365;
-SELECT @@timestamp;
SET @@timestamp = -1000000000;
SELECT @@timestamp;
diff --git a/mysql-test/suite/sys_vars/r/general_log_file_basic.result b/mysql-test/suite/sys_vars/r/general_log_file_basic.result
index 48a8d90b55e..5c0b93cf4ab 100644
--- a/mysql-test/suite/sys_vars/r/general_log_file_basic.result
+++ b/mysql-test/suite/sys_vars/r/general_log_file_basic.result
@@ -1,7 +1,6 @@
-SET @start_value = @@global.general_log_file;
SELECT @start_value;
@start_value
-test.log
+NULL
'#---------------------FN_DYNVARS_004_01-------------------------#'
SET @@global.general_log_file = DEFAULT;
SELECT RIGHT(@@global.general_log_file,10) AS log_file;
@@ -17,4 +16,4 @@ FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='general_log_file';
@@global.general_log_file = VARIABLE_VALUE
1
-SET @@global.general_log_file= @start_value;
+SET @@global.general_log_file= 'test.log';
diff --git a/mysql-test/suite/sys_vars/r/general_log_func.result b/mysql-test/suite/sys_vars/r/general_log_func.result
index 39ba90265d5..119991396e0 100644
--- a/mysql-test/suite/sys_vars/r/general_log_func.result
+++ b/mysql-test/suite/sys_vars/r/general_log_func.result
@@ -26,6 +26,7 @@ SELECT @@general_log;
INSERT into t1(name) values('Record_3');
INSERT into t1(name) values('Record_4');
## There should be a difference ##
+SET @start_value= @@global.max_allowed_packet;
SET @@global.max_allowed_packet= 1024*1024*1024;
SET @orig_file= load_file('MYSQLD_LOGFILE.orig');
SET @copy_file= load_file('MYSQLD_LOGFILE.copy');
@@ -34,3 +35,4 @@ STRCMP(@orig_file, @copy_file)
1
## Dropping tables ##
DROP TABLE t1;
+SET @@global.max_allowed_packet= @start_value;
diff --git a/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result b/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result
index 301016d4362..201f183ad0e 100644
--- a/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result
@@ -1,30 +1,23 @@
SET @global_start_value = @@global.innodb_commit_concurrency;
SELECT @global_start_value;
@global_start_value
-0
+10
'#--------------------FN_DYNVARS_046_01------------------------#'
-SET @@global.innodb_commit_concurrency = 0;
SET @@global.innodb_commit_concurrency = DEFAULT;
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-0
+10
'#---------------------FN_DYNVARS_046_02-------------------------#'
SET innodb_commit_concurrency = 1;
ERROR HY000: Variable 'innodb_commit_concurrency' is a GLOBAL variable and should be set with SET GLOBAL
SELECT @@innodb_commit_concurrency;
@@innodb_commit_concurrency
-0
+10
SELECT local.innodb_commit_concurrency;
ERROR 42S02: Unknown table 'local' in field list
SET global innodb_commit_concurrency = 0;
-SELECT @@global.innodb_commit_concurrency;
-@@global.innodb_commit_concurrency
-0
+ERROR HY000: Incorrect arguments to SET
'#--------------------FN_DYNVARS_046_03------------------------#'
-SET @@global.innodb_commit_concurrency = 0;
-SELECT @@global.innodb_commit_concurrency;
-@@global.innodb_commit_concurrency
-0
SET @@global.innodb_commit_concurrency = 1;
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
@@ -35,27 +28,17 @@ SELECT @@global.innodb_commit_concurrency;
1000
'#--------------------FN_DYNVARS_046_04-------------------------#'
SET @@global.innodb_commit_concurrency = -1;
-Warnings:
-Warning 1292 Truncated incorrect commit_concurrency value: '18446744073709551615'
-SELECT @@global.innodb_commit_concurrency;
-@@global.innodb_commit_concurrency
-1000
+SELECT @@global.innodb_commit_concurrency IN (4294967295,18446744073709551615);
+@@global.innodb_commit_concurrency IN (4294967295,18446744073709551615)
+1
SET @@global.innodb_commit_concurrency = "T";
ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency'
-SELECT @@global.innodb_commit_concurrency;
-@@global.innodb_commit_concurrency
-1000
SET @@global.innodb_commit_concurrency = "Y";
ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency'
-SELECT @@global.innodb_commit_concurrency;
-@@global.innodb_commit_concurrency
-1000
SET @@global.innodb_commit_concurrency = 1001;
-Warnings:
-Warning 1292 Truncated incorrect commit_concurrency value: '1001'
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-1000
+1001
'#----------------------FN_DYNVARS_046_05------------------------#'
SELECT @@global.innodb_commit_concurrency =
VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -65,32 +48,33 @@ VARIABLE_VALUE
1
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-1000
+1001
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_commit_concurrency';
VARIABLE_VALUE
-1000
+1001
'#---------------------FN_DYNVARS_046_06-------------------------#'
SET @@global.innodb_commit_concurrency = OFF;
ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency'
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-1000
+1001
SET @@global.innodb_commit_concurrency = ON;
ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency'
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-1000
+1001
'#---------------------FN_DYNVARS_046_07----------------------#'
SET @@global.innodb_commit_concurrency = TRUE;
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
1
SET @@global.innodb_commit_concurrency = FALSE;
+ERROR HY000: Incorrect arguments to SET
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-0
+1
SET @@global.innodb_commit_concurrency = @global_start_value;
SELECT @@global.innodb_commit_concurrency;
@@global.innodb_commit_concurrency
-0
+10
diff --git a/mysql-test/suite/sys_vars/r/log_output_basic.result b/mysql-test/suite/sys_vars/r/log_output_basic.result
index 481d5862074..6f350556ff9 100644
--- a/mysql-test/suite/sys_vars/r/log_output_basic.result
+++ b/mysql-test/suite/sys_vars/r/log_output_basic.result
@@ -1,7 +1,7 @@
SET @start_value = @@global.log_output;
SELECT @start_value;
@start_value
-FILE,TABLE
+FILE
'#--------------------FN_DYNVARS_065_01------------------------#'
SET @@global.log_output = FILE;
SET @@global.log_output = DEFAULT;
@@ -172,4 +172,4 @@ TABLE
SET @@global.log_output = @start_value;
SELECT @@global.log_output;
@@global.log_output
-FILE,TABLE
+FILE
diff --git a/mysql-test/suite/sys_vars/r/log_output_func.result b/mysql-test/suite/sys_vars/r/log_output_func.result
index 060f930a161..00a8e824f78 100644
--- a/mysql-test/suite/sys_vars/r/log_output_func.result
+++ b/mysql-test/suite/sys_vars/r/log_output_func.result
@@ -1,6 +1,5 @@
SET @start_value= @@global.log_output;
SET @start_general_log= @@global.general_log;
-SET @start_general_log_file= @@global.general_log_file;
'#--------------------FN_DYNVARS_065_01-------------------------#'
SET @@global.log_output = 'NONE';
'connect (con1,localhost,root,,,,)'
@@ -53,7 +52,7 @@ count(*)
DROP TABLE t1;
connection default;
SET @@global.general_log= 'OFF';
-SET @@global.general_log_file= @start_general_log_file;
+SET @@global.general_log_file= '/home/horst/bzr/5.1-52501/mysql-test/var/mysqld.1/mysqld.log';
SET @@global.log_output= @start_value;
SET @@global.general_log= @start_general_log;
SET @@global.general_log= 'ON';
diff --git a/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result b/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result
index 925f940a5c4..3cd62187d0b 100644
--- a/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result
+++ b/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result
@@ -1,4 +1,4 @@
-SET @start_value = @@global.slow_query_log_file;
+slowtest.log
'#---------------------FN_DYNVARS_004_01-------------------------#'
SET @@global.slow_query_log_file = DEFAULT;
SELECT RIGHT(@@global.slow_query_log_file,15);
@@ -14,4 +14,4 @@ FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='slow_query_log_file';
@@global.slow_query_log_file = VARIABLE_VALUE
1
-SET @@global.slow_query_log_file= @start_value;
+SET @@global.slow_query_log_file= 'slowtest.log';
diff --git a/mysql-test/suite/sys_vars/r/timestamp_basic_32.result b/mysql-test/suite/sys_vars/r/timestamp_basic_32.result
index a8be2201e68..87c9edc668e 100644
--- a/mysql-test/suite/sys_vars/r/timestamp_basic_32.result
+++ b/mysql-test/suite/sys_vars/r/timestamp_basic_32.result
@@ -8,14 +8,6 @@ ERROR HY000: Variable 'timestamp' is a SESSION variable and can't be used with S
'#--------------------FN_DYNVARS_001_03------------------------#'
SET @@timestamp = 0;
'Setting 0 resets timestamp to session default timestamp'
-SET @@timestamp = 123456789123456;
-SELECT @@timestamp;
-@@timestamp
-2249167232
-SET @@timestamp = 60*60*60*60*365;
-SELECT @@timestamp;
-@@timestamp
-435432704
SET @@timestamp = -1000000000;
SELECT @@timestamp;
@@timestamp
@@ -66,3 +58,7 @@ ERROR 42S02: Unknown table 'session' in field list
SELECT timestamp = @@session.timestamp;
ERROR 42S22: Unknown column 'timestamp' in 'field list'
SET @@timestamp = @session_start_value;
+SET @@timestamp = 123456789123456;
+ERROR HY000: This version of MySQL doesn't support dates later than 2038
+SET @@timestamp = 60*60*60*60*365;
+ERROR HY000: This version of MySQL doesn't support dates later than 2038
diff --git a/mysql-test/suite/sys_vars/r/timestamp_basic_64.result b/mysql-test/suite/sys_vars/r/timestamp_basic_64.result
index 824a3ea5529..b5d3979610f 100644
--- a/mysql-test/suite/sys_vars/r/timestamp_basic_64.result
+++ b/mysql-test/suite/sys_vars/r/timestamp_basic_64.result
@@ -8,14 +8,6 @@ ERROR HY000: Variable 'timestamp' is a SESSION variable and can't be used with S
'#--------------------FN_DYNVARS_001_03------------------------#'
SET @@timestamp = 0;
'Setting 0 resets timestamp to session default timestamp'
-SET @@timestamp = 123456789123456;
-SELECT @@timestamp;
-@@timestamp
-123456789123456
-SET @@timestamp = 60*60*60*60*365;
-SELECT @@timestamp;
-@@timestamp
-4730400000
SET @@timestamp = -1000000000;
SELECT @@timestamp;
@@timestamp
@@ -66,3 +58,11 @@ ERROR 42S02: Unknown table 'session' in field list
SELECT timestamp = @@session.timestamp;
ERROR 42S22: Unknown column 'timestamp' in 'field list'
SET @@timestamp = @session_start_value;
+SET @@timestamp = 123456789123456;
+SELECT @@timestamp;
+@@timestamp
+123456789123456
+SET @@timestamp = 60*60*60*60*365;
+SELECT @@timestamp;
+@@timestamp
+4730400000
diff --git a/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result b/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result
index 2ebeb8d61d8..06b624ad5c8 100644
--- a/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result
+++ b/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result
@@ -100,8 +100,6 @@ SELECT @@session.tmp_table_size;
SET @@session.tmp_table_size = "Test";
ERROR 42000: Incorrect argument type to variable 'tmp_table_size'
SET @@session.tmp_table_size = 12345678901;
-Warnings:
-Warning 1292 Truncated incorrect tmp_table_size value: '12345678901'
SELECT @@session.tmp_table_size IN (12345678901,4294967295);
@@session.tmp_table_size IN (12345678901,4294967295)
1
diff --git a/mysql-test/suite/sys_vars/t/completion_type_func.test b/mysql-test/suite/sys_vars/t/completion_type_func.test
index 8e363ed2a7d..82e2dc47e54 100644
--- a/mysql-test/suite/sys_vars/t/completion_type_func.test
+++ b/mysql-test/suite/sys_vars/t/completion_type_func.test
@@ -18,7 +18,7 @@
# server-system-variables.html#option_mysqld_completion_type #
# #
################################################################################
-
+--source include/not_embedded.inc
--source include/have_innodb.inc
--disable_warnings
diff --git a/mysql-test/suite/sys_vars/t/disabled.def b/mysql-test/suite/sys_vars/t/disabled.def
new file mode 100644
index 00000000000..915ea7a6f5c
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/disabled.def
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# List the test cases that are to be disabled temporarily.
+#
+# Separate the test case name and the comment with ':'.
+#
+# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
+#
+# Do not use any TAB characters for whitespace.
+#
+##############################################################################
+sys_vars.max_binlog_cache_size_basic_64 : bug#56408 2010-08-31 Horst
+sys_vars.max_binlog_cache_size_basic_32 : bug#56408 2010-08-31 Horst
diff --git a/mysql-test/suite/sys_vars/t/general_log_file_basic.test b/mysql-test/suite/sys_vars/t/general_log_file_basic.test
index 014108f88d2..35905bad987 100644
--- a/mysql-test/suite/sys_vars/t/general_log_file_basic.test
+++ b/mysql-test/suite/sys_vars/t/general_log_file_basic.test
@@ -35,7 +35,8 @@
# Saving initial value of general_log_file in a temporary variable #
########################################################################
-SET @start_value = @@global.general_log_file;
+#SET @start_value = @@global.general_log_file;
+LET $start_value = `SELECT @@global.general_log_file`;
SELECT @start_value;
@@ -68,7 +69,8 @@ SELECT @@global.general_log_file = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='general_log_file';
-SET @@global.general_log_file= @start_value;
+#SET @@global.general_log_file= @start_value;
+eval SET @@global.general_log_file= '$start_value';
#####################################################
# END OF general_log_file TESTS #
diff --git a/mysql-test/suite/sys_vars/t/general_log_func.test b/mysql-test/suite/sys_vars/t/general_log_func.test
index 24d535e88e5..d355d0d619c 100644
--- a/mysql-test/suite/sys_vars/t/general_log_func.test
+++ b/mysql-test/suite/sys_vars/t/general_log_func.test
@@ -79,6 +79,7 @@ INSERT into t1(name) values('Record_4');
--chmod 0777 $MYSQLD_LOGFILE.orig
--echo ## There should be a difference ##
+SET @start_value= @@global.max_allowed_packet;
SET @@global.max_allowed_packet= 1024*1024*1024;
--replace_result $MYSQLD_LOGFILE MYSQLD_LOGFILE
eval SET @orig_file= load_file('$MYSQLD_LOGFILE.orig');
@@ -91,3 +92,4 @@ eval SELECT STRCMP(@orig_file, @copy_file);
--echo ## Dropping tables ##
DROP TABLE t1;
+SET @@global.max_allowed_packet= @start_value;
diff --git a/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt
new file mode 100644
index 00000000000..727bbc4b11b
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt
@@ -0,0 +1 @@
+--innodb-commit-concurrency=10
diff --git a/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test
index 1ef69e34999..2c7645f3b25 100644
--- a/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test
@@ -11,6 +11,10 @@
# Creation Date: 2008-02-07 #
# Author: Rizwan #
# #
+# Modified 2010-09-01 Horst #
+# Added amaster.opt with innodb-commit-concurrency > 0 to be able to assign #
+# different values <> 0 #
+# #
#Description:Test Cases of Dynamic System Variable innodb_commit_concurrency #
# that checks the behavior of this variable in the following ways #
# * Default Value #
@@ -43,7 +47,6 @@ SELECT @global_start_value;
# Display the DEFAULT value of innodb_commit_concurrency #
########################################################################
-SET @@global.innodb_commit_concurrency = 0;
SET @@global.innodb_commit_concurrency = DEFAULT;
SELECT @@global.innodb_commit_concurrency;
@@ -60,20 +63,14 @@ SELECT @@innodb_commit_concurrency;
--Error ER_UNKNOWN_TABLE
SELECT local.innodb_commit_concurrency;
+--error ER_WRONG_ARGUMENTS
SET global innodb_commit_concurrency = 0;
-SELECT @@global.innodb_commit_concurrency;
-
-
--echo '#--------------------FN_DYNVARS_046_03------------------------#'
##########################################################################
# change the value of innodb_commit_concurrency to a valid value #
##########################################################################
-
-SET @@global.innodb_commit_concurrency = 0;
-SELECT @@global.innodb_commit_concurrency;
-
SET @@global.innodb_commit_concurrency = 1;
SELECT @@global.innodb_commit_concurrency;
SET @@global.innodb_commit_concurrency = 1000;
@@ -85,15 +82,13 @@ SELECT @@global.innodb_commit_concurrency;
###########################################################################
SET @@global.innodb_commit_concurrency = -1;
-SELECT @@global.innodb_commit_concurrency;
+SELECT @@global.innodb_commit_concurrency IN (4294967295,18446744073709551615);
--Error ER_WRONG_TYPE_FOR_VAR
SET @@global.innodb_commit_concurrency = "T";
-SELECT @@global.innodb_commit_concurrency;
--Error ER_WRONG_TYPE_FOR_VAR
SET @@global.innodb_commit_concurrency = "Y";
-SELECT @@global.innodb_commit_concurrency;
SET @@global.innodb_commit_concurrency = 1001;
SELECT @@global.innodb_commit_concurrency;
@@ -131,6 +126,7 @@ SELECT @@global.innodb_commit_concurrency;
SET @@global.innodb_commit_concurrency = TRUE;
SELECT @@global.innodb_commit_concurrency;
+--error ER_WRONG_ARGUMENTS
SET @@global.innodb_commit_concurrency = FALSE;
SELECT @@global.innodb_commit_concurrency;
diff --git a/mysql-test/suite/sys_vars/t/log_output_func.test b/mysql-test/suite/sys_vars/t/log_output_func.test
index 007c4f38659..8a2fbe0728b 100644
--- a/mysql-test/suite/sys_vars/t/log_output_func.test
+++ b/mysql-test/suite/sys_vars/t/log_output_func.test
@@ -26,7 +26,8 @@
SET @start_value= @@global.log_output;
SET @start_general_log= @@global.general_log;
-SET @start_general_log_file= @@global.general_log_file;
+#SET @start_general_log_file= @@global.general_log_file;
+LET $start_general_log_file= `SELECT @@global.general_log_file`;
--echo '#--------------------FN_DYNVARS_065_01-------------------------#'
##################################################################
@@ -113,7 +114,8 @@ file_exists $MYSQLTEST_VARDIR/run/mytest.log ;
--echo connection default;
connection default;
SET @@global.general_log= 'OFF';
-SET @@global.general_log_file= @start_general_log_file;
+#SET @@global.general_log_file= @start_general_log_file;
+eval SET @@global.general_log_file= '$start_general_log_file';
SET @@global.log_output= @start_value;
SET @@global.general_log= @start_general_log;
SET @@global.general_log= 'ON';
diff --git a/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt
new file mode 100644
index 00000000000..d392e2e4262
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt
@@ -0,0 +1 @@
+--log-error='dummy.log'
diff --git a/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test
index 37dd3a5a297..441e9c72982 100644
--- a/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test
+++ b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test
@@ -19,6 +19,9 @@
# #
################################################################################
+# due to bug#56486
+--source include/not_windows.inc
+
--echo '#--------------------FN_DYNVARS_093_01-------------------------#'
###############################################################################
# Check if setting myisam_data_pointer_size is changed in every new connection#
diff --git a/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test b/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test
index f2c66eb3a0a..2cc31c91388 100644
--- a/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test
+++ b/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test
@@ -55,7 +55,7 @@ DROP TABLE t1;
eval SELECT @@global.init_slave = $my_init_slave;
--echo Expect 1
# wait for the slave threads have set the global variable.
-let $wait_timeout= 90;
+let $wait_timeout= 240;
let $wait_condition= SELECT @@global.max_connections = @start_max_connections;
--source include/wait_condition_sp.inc
# check that the action in init_slave does not happen immediately
diff --git a/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test b/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test
index 9125b686cad..810588b8f4e 100644
--- a/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test
+++ b/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test
@@ -35,7 +35,9 @@
# Saving initial value of slow_query_log_file in a temporary variable #
###########################################################################
-SET @start_value = @@global.slow_query_log_file;
+#SET @start_value = @@global.slow_query_log_file;
+LET $start_value = `SELECT @@global.slow_query_log_file`;
+--echo $start_value
--echo '#---------------------FN_DYNVARS_004_01-------------------------#'
###############################################
@@ -65,7 +67,9 @@ SELECT @@global.slow_query_log_file = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='slow_query_log_file';
-SET @@global.slow_query_log_file= @start_value;
+#SET @@global.slow_query_log_file= @start_value;
+eval SET @@global.slow_query_log_file= '$start_value';
+#SELECT @start_value;
#####################################################
# END OF slow_query_log_file TESTS #
#####################################################
diff --git a/mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt b/mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt
new file mode 100644
index 00000000000..875ecc54b55
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt
@@ -0,0 +1 @@
+--general-log --log-output=TABLE,FILE
diff --git a/mysql-test/suite/sys_vars/t/timestamp_basic_32.test b/mysql-test/suite/sys_vars/t/timestamp_basic_32.test
index a2b6139aef9..11b7535d9ef 100644
--- a/mysql-test/suite/sys_vars/t/timestamp_basic_32.test
+++ b/mysql-test/suite/sys_vars/t/timestamp_basic_32.test
@@ -7,3 +7,7 @@
--source include/have_32bit.inc
--source suite/sys_vars/inc/timestamp_basic.inc
+--error ER_UNKNOWN_ERROR
+SET @@timestamp = 123456789123456;
+--error ER_UNKNOWN_ERROR
+SET @@timestamp = 60*60*60*60*365;
diff --git a/mysql-test/suite/sys_vars/t/timestamp_basic_64.test b/mysql-test/suite/sys_vars/t/timestamp_basic_64.test
index fbc86316ed9..5180c86392a 100644
--- a/mysql-test/suite/sys_vars/t/timestamp_basic_64.test
+++ b/mysql-test/suite/sys_vars/t/timestamp_basic_64.test
@@ -7,3 +7,8 @@
--source include/have_64bit.inc
--source suite/sys_vars/inc/timestamp_basic.inc
+SET @@timestamp = 123456789123456;
+SELECT @@timestamp;
+SET @@timestamp = 60*60*60*60*365;
+SELECT @@timestamp;
+
diff --git a/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test b/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test
index c2ff51d50ca..116196ddb07 100644
--- a/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test
+++ b/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test
@@ -133,8 +133,9 @@ SELECT @@session.tmp_table_size;
--Error ER_WRONG_TYPE_FOR_VAR
SET @@session.tmp_table_size = "Test";
+--disable_warnings
SET @@session.tmp_table_size = 12345678901;
-
+--enable_warnings
# With a 64 bit mysqld:12345678901,with a 32 bit mysqld: 4294967295
SELECT @@session.tmp_table_size IN (12345678901,4294967295);
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 9c5e091e03b..4510652b03f 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -13,3 +13,5 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
main.mysqlhotcopy_myisam : Bug#56817 2010-10-21 anitha mysqlhotcopy* fails
main.mysqlhotcopy_archive: Bug#56817 2010-10-21 anitha mysqlhotcopy* fails
+log_tables-big : Bug#48646 2010-11-15 mattiasj report already exists
+read_many_rows_innodb : Bug#37635 2010-11-15 mattiasj report already exists
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index e764906c374..8fce7072319 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -849,4 +849,14 @@ INSERT INTO t1 VALUES (0),(9.216e-096);
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
DROP TABLE t1;
+--echo #
+--echo # Bug #52160: crash and inconsistent results when grouping
+--echo # by a function and column
+--echo #
+
+CREATE TABLE t1(a CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES (''),('');
+SELECT COUNT(*) FROM t1 GROUP BY TIME_TO_SEC(a);
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/key_cache-master.opt b/mysql-test/t/key_cache-master.opt
index 66e19c18a8a..6398e3e0a26 100644
--- a/mysql-test/t/key_cache-master.opt
+++ b/mysql-test/t/key_cache-master.opt
@@ -1 +1,2 @@
--key_buffer_size=2M --small.key_buffer_size=256K --small.key_buffer_size=128K
+--force-restart
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index 076f2e8bc3b..af6c34dec37 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -1027,6 +1027,25 @@ DROP TABLE t1;
TRUNCATE TABLE mysql.slow_log;
+#
+# Bug #47924 main.log_tables times out sporadically
+#
+
+use mysql;
+# Should result in error
+--disable_warnings
+drop table if exists renamed_general_log;
+drop table if exists renamed_slow_log;
+--enable_warnings
+--error ER_CANT_RENAME_LOG_TABLE
+RENAME TABLE general_log TO renamed_general_log;
+--error ER_CANT_RENAME_LOG_TABLE
+RENAME TABLE slow_log TO renamed_slow_log;
+
+use test;
+flush tables with read lock;
+unlock tables;
+
SET @@session.long_query_time= @old_long_query_time;
SET @@global.log_output= @old_log_output;
diff --git a/mysql-test/t/mysqlbinlog-master.opt b/mysql-test/t/mysqlbinlog-master.opt
index ac1a87c73b3..a9f4a6010d8 100644
--- a/mysql-test/t/mysqlbinlog-master.opt
+++ b/mysql-test/t/mysqlbinlog-master.opt
@@ -1 +1,2 @@
--max-binlog-size=4096
+--force-restart
diff --git a/mysql-test/t/sp-bugs.test b/mysql-test/t/sp-bugs.test
index 8aa0791e265..fe52632c784 100644
--- a/mysql-test/t/sp-bugs.test
+++ b/mysql-test/t/sp-bugs.test
@@ -101,4 +101,41 @@ CALL p1 ();
DROP TABLE t1;
DROP PROCEDURE p1;
+--echo #
+--echo # Bug#54375: Error in stored procedure leaves connection
+--echo # in different default schema
+--echo #
+
+--disable_warnings
+SET @@SQL_MODE = 'STRICT_ALL_TABLES';
+DROP DATABASE IF EXISTS db1;
+CREATE DATABASE db1;
+USE db1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 int NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+DELIMITER $$;
+CREATE FUNCTION f1 (
+ some_value int
+)
+RETURNS smallint
+DETERMINISTIC
+BEGIN
+ INSERT INTO t1 SET c1 = some_value;
+ RETURN(LAST_INSERT_ID());
+END$$
+DELIMITER ;$$
+DROP DATABASE IF EXISTS db2;
+CREATE DATABASE db2;
+--enable_warnings
+USE db2;
+SELECT DATABASE();
+--error ER_DUP_ENTRY
+SELECT db1.f1(1);
+SELECT DATABASE();
+USE test;
+DROP FUNCTION db1.f1;
+DROP TABLE db1.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
--echo End of 5.1 tests
diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test
index 460da1c1614..4e097edf73d 100644
--- a/mysql-test/t/type_blob.test
+++ b/mysql-test/t/type_blob.test
@@ -612,3 +612,19 @@ explain select convert(1, binary(4294967296));
explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
--echo End of 5.0 tests
+
+--echo # Bug #52160: crash and inconsistent results when grouping
+--echo # by a function and column
+
+CREATE FUNCTION f1() RETURNS TINYBLOB RETURN 1;
+
+CREATE TABLE t1(a CHAR(1));
+INSERT INTO t1 VALUES ('0'), ('0');
+
+SELECT COUNT(*) FROM t1 GROUP BY f1(), a;
+
+DROP FUNCTION f1;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
+
diff --git a/mysql-test/t/variables-big.test b/mysql-test/t/variables-big.test
index fdb11ffa907..6c357bb6e54 100644
--- a/mysql-test/t/variables-big.test
+++ b/mysql-test/t/variables-big.test
@@ -37,19 +37,19 @@
--disable_warnings
SET SESSION transaction_prealloc_size=1024*1024*1024*1;
---replace_column 1 <Id> 6 <Time>
+--replace_column 1 <Id> 3 <Host> 6 <Time>
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*2;
---replace_column 1 <Id> 6 <Time>
+--replace_column 1 <Id> 3 <Host> 6 <Time>
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*3;
---replace_column 1 <Id> 6 <Time>
+--replace_column 1 <Id> 3 <Host> 6 <Time>
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*4;
---replace_column 1 <Id> 6 <Time>
+--replace_column 1 <Id> 3 <Host> 6 <Time>
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*5;
---replace_column 1 <Id> 6 <Time>
+--replace_column 1 <Id> 3 <Host> 6 <Time>
SHOW PROCESSLIST;
--enable_warnings
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 8042dc2828b..b7faf7c1b95 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -3917,11 +3917,11 @@ restart:
if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
BLOCK_REASSIGNED)))
{
- struct st_hash_link *next_hash_link;
- my_off_t next_diskpos;
- File next_file;
- uint next_status;
- uint hash_requests;
+ struct st_hash_link *UNINIT_VAR(next_hash_link);
+ my_off_t UNINIT_VAR(next_diskpos);
+ File UNINIT_VAR(next_file);
+ uint UNINIT_VAR(next_status);
+ uint UNINIT_VAR(hash_requests);
total_found++;
found++;
diff --git a/mysys/my_getncpus.c b/mysys/my_getncpus.c
index 82e87dee2e4..f9db6603924 100644
--- a/mysys/my_getncpus.c
+++ b/mysys/my_getncpus.c
@@ -18,9 +18,10 @@
#include "mysys_priv.h"
#include <unistd.h>
+#ifdef _SC_NPROCESSORS_ONLN
+
static int ncpus=0;
-#ifdef _SC_NPROCESSORS_ONLN
int my_getncpus()
{
if (!ncpus)
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 7bac8017324..ebd84548a9b 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -318,6 +318,9 @@ end:
/* Produce a core for the thread */
void my_write_core(int sig)
{
+#ifdef HAVE_gcov
+ extern void __gcov_flush(void);
+#endif
signal(sig, SIG_DFL);
#ifdef HAVE_gcov
/*
@@ -325,7 +328,6 @@ void my_write_core(int sig)
information from this process, causing gcov output to be incomplete.
So we force the writing of coverage information here before terminating.
*/
- extern void __gcov_flush(void);
__gcov_flush();
#endif
pthread_kill(pthread_self(), sig);
diff --git a/pstack/Makefile.am b/pstack/Makefile.am
deleted file mode 100644
index 870fed6ceeb..00000000000
--- a/pstack/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2000-2003, 2005 MySQL AB
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-#
-# As pstack doesn't work on all configurations, we have to use
-# the USE_PSTACK hack to get all files into distribution
-#
-
-SUBDIRS = aout
-
-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
-
-pkglib_LIBRARIES = libpstack.a
-libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c \
- debug.c ieee.c pstack.c stabs.c
-noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \
- linuxthreads.h pstack.h pstacktrace.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/pstack/aout/Makefile.am b/pstack/aout/Makefile.am
deleted file mode 100644
index 2e61555db87..00000000000
--- a/pstack/aout/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-noinst_HEADERS = aout64.h stab.def stab_gnu.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/pstack/aout/aout64.h b/pstack/aout/aout64.h
deleted file mode 100644
index 76f1140b682..00000000000
--- a/pstack/aout/aout64.h
+++ /dev/null
@@ -1,475 +0,0 @@
-/* `a.out' object-file definitions, including extensions to 64-bit fields */
-
-#ifndef __A_OUT_64_H__
-#define __A_OUT_64_H__
-
-/* This is the layout on disk of the 32-bit or 64-bit exec header. */
-
-#ifndef external_exec
-struct external_exec
-{
- bfd_byte e_info[4]; /* magic number and stuff */
- bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */
- bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */
- bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */
- bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */
- bfd_byte e_entry[BYTES_IN_WORD]; /* start address */
- bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */
- bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
-};
-
-#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
-
-/* Magic numbers for a.out files */
-
-#if ARCH_SIZE==64
-#define OMAGIC 0x1001 /* Code indicating object file */
-#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */
-#define NMAGIC 0x1003 /* Code indicating pure executable. */
-
-/* There is no 64-bit QMAGIC as far as I know. */
-
-#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
- && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC)
-#else
-#define OMAGIC 0407 /* ...object file or impure executable. */
-#define NMAGIC 0410 /* Code indicating pure executable. */
-#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
-#define BMAGIC 0415 /* Used by a b.out object. */
-
-/* This indicates a demand-paged executable with the header in the text.
- It is used by 386BSD (and variants) and Linux, at least. */
-#ifndef QMAGIC
-#define QMAGIC 0314
-#endif
-# ifndef N_BADMAG
-# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
- && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC \
- && N_MAGIC(x) != QMAGIC)
-# endif /* N_BADMAG */
-#endif
-
-#endif
-
-#ifdef QMAGIC
-#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC)
-#else
-#define N_IS_QMAGIC(x) (0)
-#endif
-
-/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is
- the finest granularity at which you can page something, thus it
- controls the padding (if any) before the text segment of a ZMAGIC
- file. N_SEGSIZE is the resolution at which things can be marked as
- read-only versus read/write, so it controls the padding between the
- text segment and the data segment (in memory; on disk the padding
- between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same
- for most machines, but different for sun3. */
-
-/* By default, segment size is constant. But some machines override this
- to be a function of the a.out header (e.g. machine type). */
-
-#ifndef N_SEGSIZE
-#define N_SEGSIZE(x) SEGMENT_SIZE
-#endif
-
-/* Virtual memory address of the text section.
- This is getting very complicated. A good reason to discard a.out format
- for something that specifies these fields explicitly. But til then...
-
- * OMAGIC and NMAGIC files:
- (object files: text for "relocatable addr 0" right after the header)
- start at 0, offset is EXEC_BYTES_SIZE, size as stated.
- * The text address, offset, and size of ZMAGIC files depend
- on the entry point of the file:
- * entry point below TEXT_START_ADDR:
- (hack for SunOS shared libraries)
- start at 0, offset is 0, size as stated.
- * If N_HEADER_IN_TEXT(x) is true (which defaults to being the
- case when the entry point is EXEC_BYTES_SIZE or further into a page):
- no padding is needed; text can start after exec header. Sun
- considers the text segment of such files to include the exec header;
- for BFD's purposes, we don't, which makes more work for us.
- start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE,
- size as stated minus EXEC_BYTES_SIZE.
- * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when
- the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page
- aligned)): (padding is needed so that text can start at a page boundary)
- start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated.
-
- Specific configurations may want to hardwire N_HEADER_IN_TEXT,
- for efficiency or to allow people to play games with the entry point.
- In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos,
- and as 0 for most other hosts (Sony News, Vax Ultrix, etc).
- (Do this in the appropriate bfd target file.)
- (The default is a heuristic that will break if people try changing
- the entry point, perhaps with the ld -e flag.)
-
- * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true,
- and for which the starting address is TARGET_PAGE_SIZE (or should this be
- SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC).
- */
-
-/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header
- in the text. */
-#ifndef N_HEADER_IN_TEXT
-#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
-#endif
-
-/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC
- files. */
-#ifndef N_SHARED_LIB
-#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
-#endif
-
-/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
- the assumption that we are dealing with a .o file, not an
- executable. This is necessary for OMAGIC (but means we don't work
- right on the output from ld -N); more questionable for NMAGIC. */
-
-#ifndef N_TXTADDR
-#define N_TXTADDR(x) \
- (/* The address of a QMAGIC file is always one page in, */ \
- /* with the header in the text. */ \
- N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \
- N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\
- N_SHARED_LIB(x) ? 0 : \
- N_HEADER_IN_TEXT(x) ? \
- TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\
- TEXT_START_ADDR /* a page of padding */\
- )
-#endif
-
-/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
- to make the text segment start at a certain boundary. For most
- systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the
- time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
- not what TARGET_PAGE_SIZE needs to be for QMAGIC. */
-
-#ifndef ZMAGIC_DISK_BLOCK_SIZE
-#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE
-#endif
-
-#define N_DISK_BLOCK_SIZE(x) \
- (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE)
-
-/* Offset in an a.out of the start of the text section. */
-#ifndef N_TXTOFF
-#define N_TXTOFF(x) \
- (/* For {O,N,Q}MAGIC, no padding. */ \
- N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \
- N_SHARED_LIB(x) ? 0 : \
- N_HEADER_IN_TEXT(x) ? \
- EXEC_BYTES_SIZE : /* no padding */\
- ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\
- )
-#endif
-/* Size of the text section. It's always as stated, except that we
- offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF
- for ZMAGIC files that nominally include the exec header
- as part of the first page of text. (BFD doesn't consider the
- exec header to be part of the text segment.) */
-#ifndef N_TXTSIZE
-#define N_TXTSIZE(x) \
- (/* For QMAGIC, we don't consider the header part of the text section. */\
- N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \
- (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \
- N_HEADER_IN_TEXT(x) ? \
- (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
- (x).a_text /* a page of padding */\
- )
-#endif
-/* The address of the data segment in virtual memory.
- It is the text segment address, plus text segment size, rounded
- up to a N_SEGSIZE boundary for pure or pageable files. */
-#ifndef N_DATADDR
-#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
- : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
-#endif
-/* The address of the BSS segment -- immediately after the data segment. */
-
-#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
-
-/* Offsets of the various portions of the file after the text segment. */
-
-/* For {Q,Z}MAGIC, there is padding to make the data segment start on
- a page boundary. Most of the time the a_text field (and thus
- N_TXTSIZE) already contains this padding. It is possible that for
- BSDI and/or 386BSD it sometimes doesn't contain the padding, and
- perhaps we should be adding it here. But this seems kind of
- questionable and probably should be BSDI/386BSD-specific if we do
- do it.
-
- For NMAGIC (at least for hp300 BSD, probably others), there is
- padding in memory only, not on disk, so we must *not* ever pad here
- for NMAGIC. */
-
-#ifndef N_DATOFF
-#define N_DATOFF(x) \
- (N_TXTOFF(x) + N_TXTSIZE(x))
-#endif
-
-#ifndef N_TRELOFF
-#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
-#endif
-#ifndef N_DRELOFF
-#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
-#endif
-#ifndef N_SYMOFF
-#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
-#endif
-#ifndef N_STROFF
-#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
-#endif
-
-/* Symbols */
-#ifndef external_nlist
-struct external_nlist {
- bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
- bfd_byte e_type[1]; /* type of symbol */
- bfd_byte e_other[1]; /* misc info (usually empty) */
- bfd_byte e_desc[2]; /* description field */
- bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
-};
-#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
-#endif
-
-struct internal_nlist {
- unsigned long n_strx; /* index into string table of name */
- unsigned char n_type; /* type of symbol */
- unsigned char n_other; /* misc info (usually empty) */
- unsigned short n_desc; /* description field */
- bfd_vma n_value; /* value of symbol */
-};
-
-/* The n_type field is the symbol type, containing: */
-
-#define N_UNDF 0 /* Undefined symbol */
-#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
-#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
-#define N_DATA 6 /* Data sym -- defined at offset in data seg */
-#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
-#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
-#define N_FN 0x1f /* File name of .o file */
-#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
-/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
- N_DATA, or N_BSS. When the low-order bit of other types is set,
- (e.g. N_WARNING versus N_FN), they are two different types. */
-#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
-#define N_TYPE 0x1e
-#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
-
-#define N_INDR 0x0a
-
-/* The following symbols refer to set elements.
- All the N_SET[ATDB] symbols with the same name form one set.
- Space is allocated for the set in the text section, and each set
- elements value is stored into one word of the space.
- The first word of the space is the length of the set (number of elements).
-
- The address of the set is made into an N_SETV symbol
- whose name is the same as the name of the set.
- This symbol acts like a N_DATA global symbol
- in that it can satisfy undefined external references. */
-
-/* These appear as input to LD, in a .o file. */
-#define N_SETA 0x14 /* Absolute set element symbol */
-#define N_SETT 0x16 /* Text set element symbol */
-#define N_SETD 0x18 /* Data set element symbol */
-#define N_SETB 0x1A /* Bss set element symbol */
-
-/* This is output from LD. */
-#define N_SETV 0x1C /* Pointer to set vector in data area. */
-
-/* Warning symbol. The text gives a warning message, the next symbol
- in the table will be undefined. When the symbol is referenced, the
- message is printed. */
-
-#define N_WARNING 0x1e
-
-/* Weak symbols. These are a GNU extension to the a.out format. The
- semantics are those of ELF weak symbols. Weak symbols are always
- externally visible. The N_WEAK? values are squeezed into the
- available slots. The value of a N_WEAKU symbol is 0. The values
- of the other types are the definitions. */
-#define N_WEAKU 0x0d /* Weak undefined symbol. */
-#define N_WEAKA 0x0e /* Weak absolute symbol. */
-#define N_WEAKT 0x0f /* Weak text symbol. */
-#define N_WEAKD 0x10 /* Weak data symbol. */
-#define N_WEAKB 0x11 /* Weak bss symbol. */
-
-/* Relocations
-
- There are two types of relocation flavours for a.out systems,
- standard and extended. The standard form is used on systems where the
- instruction has room for all the bits of an offset to the operand, whilst
- the extended form is used when an address operand has to be split over n
- instructions. Eg, on the 68k, each move instruction can reference
- the target with a displacement of 16 or 32 bits. On the sparc, move
- instructions use an offset of 14 bits, so the offset is stored in
- the reloc field, and the data in the section is ignored.
-*/
-
-/* This structure describes a single relocation to be performed.
- The text-relocation section of the file is a vector of these structures,
- all of which apply to the text section.
- Likewise, the data-relocation section applies to the data section. */
-
-struct reloc_std_external {
- bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
- bfd_byte r_index[3]; /* symbol table index of symbol */
- bfd_byte r_type[1]; /* relocation type */
-};
-
-#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
-#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
-
-#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
-#define RELOC_STD_BITS_LENGTH_SH_BIG 5
-#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
-#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
-
-#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
-#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
-
-#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
-#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
-
-#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
-#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
-
-#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
-#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
-
-#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
-
-struct reloc_std_internal
-{
- bfd_vma r_address; /* Address (within segment) to be relocated. */
- /* The meaning of r_symbolnum depends on r_extern. */
- unsigned int r_symbolnum:24;
- /* Nonzero means value is a pc-relative offset
- and it should be relocated for changes in its own address
- as well as for changes in the symbol or section specified. */
- unsigned int r_pcrel:1;
- /* Length (as exponent of 2) of the field to be relocated.
- Thus, a value of 2 indicates 1<<2 bytes. */
- unsigned int r_length:2;
- /* 1 => relocate with value of symbol.
- r_symbolnum is the index of the symbol
- in files the symbol table.
- 0 => relocate with the address of a segment.
- r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
- (the N_EXT bit may be set also, but signifies nothing). */
- unsigned int r_extern:1;
- /* The next three bits are for SunOS shared libraries, and seem to
- be undocumented. */
- unsigned int r_baserel:1; /* Linkage table relative */
- unsigned int r_jmptable:1; /* pc-relative to jump table */
- unsigned int r_relative:1; /* "relative relocation" */
- /* unused */
- unsigned int r_pad:1; /* Padding -- set to zero */
-};
-
-
-/* EXTENDED RELOCS */
-
-struct reloc_ext_external {
- bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
- bfd_byte r_index[3]; /* symbol table index of symbol */
- bfd_byte r_type[1]; /* relocation type */
- bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
-};
-
-#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
-#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
-
-#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
-#define RELOC_EXT_BITS_TYPE_SH_BIG 0
-#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
-#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
-
-/* Bytes per relocation entry */
-#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
-
-enum reloc_type
-{
- /* simple relocations */
- RELOC_8, /* data[0:7] = addend + sv */
- RELOC_16, /* data[0:15] = addend + sv */
- RELOC_32, /* data[0:31] = addend + sv */
- /* pc-rel displacement */
- RELOC_DISP8, /* data[0:7] = addend - pc + sv */
- RELOC_DISP16, /* data[0:15] = addend - pc + sv */
- RELOC_DISP32, /* data[0:31] = addend - pc + sv */
- /* Special */
- RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */
- RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */
- RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */
- RELOC_22, /* data[0:21] = (addend + sv) */
- RELOC_13, /* data[0:12] = (addend + sv) */
- RELOC_LO10, /* data[0:9] = (addend + sv) */
- RELOC_SFA_BASE,
- RELOC_SFA_OFF13,
- /* P.I.C. (base-relative) */
- RELOC_BASE10, /* Not sure - maybe we can do this the */
- RELOC_BASE13, /* right way now */
- RELOC_BASE22,
- /* for some sort of pc-rel P.I.C. (?) */
- RELOC_PC10,
- RELOC_PC22,
- /* P.I.C. jump table */
- RELOC_JMP_TBL,
- /* reputedly for shared libraries somehow */
- RELOC_SEGOFF16,
- RELOC_GLOB_DAT,
- RELOC_JMP_SLOT,
- RELOC_RELATIVE,
-
- RELOC_11,
- RELOC_WDISP2_14,
- RELOC_WDISP19,
- RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */
- RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */
-
- /* 29K relocation types */
- RELOC_JUMPTARG,
- RELOC_CONST,
- RELOC_CONSTH,
-
- /* All the new ones I can think of, for sparc v9 */
-
- RELOC_64, /* data[0:63] = addend + sv */
- RELOC_DISP64, /* data[0:63] = addend - pc + sv */
- RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
- RELOC_DISP21, /* data[0:20] = addend - pc + sv */
- RELOC_DISP14, /* data[0:13] = addend - pc + sv */
- /* Q .
- What are the other ones,
- Since this is a clean slate, can we throw away the ones we dont
- understand ? Should we sort the values ? What about using a
- microcode format like the 68k ?
- */
- NO_RELOC
- };
-
-
-struct reloc_internal {
- bfd_vma r_address; /* offset of of data to relocate */
- long r_index; /* symbol table index of symbol */
- enum reloc_type r_type; /* relocation type */
- bfd_vma r_addend; /* datum addend */
-};
-
-/* Q.
- Should the length of the string table be 4 bytes or 8 bytes ?
-
- Q.
- What about archive indexes ?
-
- */
-
-#endif /* __A_OUT_64_H__ */
diff --git a/pstack/aout/stab.def b/pstack/aout/stab.def
deleted file mode 100644
index 3c6b456d3a9..00000000000
--- a/pstack/aout/stab.def
+++ /dev/null
@@ -1,264 +0,0 @@
-/* Table of DBX symbol codes for the GNU system.
- Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
- overlaps the N_UNDF used for ordinary symbols. In ELF files, the
- debug information is in a different file section, so there is no conflict.
- This symbol's n_value gives the size of the string section associated
- with this file. The symbol's n_strx (relative to the just-updated
- string section start address) gives the name of the source file,
- e.g. "foo.c", without any path information. The symbol's n_desc gives
- the count of upcoming symbols associated with this file (not including
- this one). */
-/* __define_stab (N_UNDF, 0x00, "UNDF") */
-
-/* Global variable. Only the name is significant.
- To find the address, look in the corresponding external symbol. */
-__define_stab (N_GSYM, 0x20, "GSYM")
-
-/* Function name for BSD Fortran. Only the name is significant.
- To find the address, look in the corresponding external symbol. */
-__define_stab (N_FNAME, 0x22, "FNAME")
-
-/* Function name or text-segment variable for C. Value is its address.
- Desc is supposedly starting line number, but GCC doesn't set it
- and DBX seems not to miss it. */
-__define_stab (N_FUN, 0x24, "FUN")
-
-/* Data-segment variable with internal linkage. Value is its address.
- "Static Sym". */
-__define_stab (N_STSYM, 0x26, "STSYM")
-
-/* BSS-segment variable with internal linkage. Value is its address. */
-__define_stab (N_LCSYM, 0x28, "LCSYM")
-
-/* Name of main routine. Only the name is significant. */
-__define_stab (N_MAIN, 0x2a, "MAIN")
-
-/* Solaris2: Read-only data symbols. */
-__define_stab (N_ROSYM, 0x2c, "ROSYM")
-
-/* Global symbol in Pascal.
- Supposedly the value is its line number; I'm skeptical. */
-__define_stab (N_PC, 0x30, "PC")
-
-/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
-__define_stab (N_NSYMS, 0x32, "NSYMS")
-
-/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
-__define_stab (N_NOMAP, 0x34, "NOMAP")
-
-/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
- a row provide the build directory and the relative path of the .o from it.
- Solaris2 uses this to avoid putting the stabs info into the linked
- executable; this stab goes into the ".stab.index" section, and the debugger
- reads the real stabs directly from the .o files instead. */
-__define_stab (N_OBJ, 0x38, "OBJ")
-
-/* New stab from Solaris 2. Options for the debugger, related to the
- source language for this module. E.g. whether to use ANSI
- integral promotions or traditional integral promotions. */
-__define_stab (N_OPT, 0x3c, "OPT")
-
-/* Register variable. Value is number of register. */
-__define_stab (N_RSYM, 0x40, "RSYM")
-
-/* Modula-2 compilation unit. Can someone say what info it contains? */
-__define_stab (N_M2C, 0x42, "M2C")
-
-/* Line number in text segment. Desc is the line number;
- value is corresponding address. On Solaris2, the line number is
- relative to the start of the current function. */
-__define_stab (N_SLINE, 0x44, "SLINE")
-
-/* Similar, for data segment. */
-__define_stab (N_DSLINE, 0x46, "DSLINE")
-
-/* Similar, for bss segment. */
-__define_stab (N_BSLINE, 0x48, "BSLINE")
-
-/* Sun's source-code browser stabs. ?? Don't know what the fields are.
- Supposedly the field is "path to associated .cb file". THIS VALUE
- OVERLAPS WITH N_BSLINE! */
-__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
-
-/* GNU Modula-2 definition module dependency. Value is the modification time
- of the definition file. Other is non-zero if it is imported with the
- GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
- are enough empty fields? */
-__define_stab(N_DEFD, 0x4a, "DEFD")
-
-/* New in Solaris2. Function start/body/end line numbers. */
-__define_stab(N_FLINE, 0x4C, "FLINE")
-
-/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
- and one is for C++. Still,... */
-/* GNU C++ exception variable. Name is variable name. */
-__define_stab (N_EHDECL, 0x50, "EHDECL")
-/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
-__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
-
-/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
- this entry is immediately followed by a CAUGHT stab saying what exception
- was caught. Multiple CAUGHT stabs means that multiple exceptions
- can be caught here. If Desc is 0, it means all exceptions are caught
- here. */
-__define_stab (N_CATCH, 0x54, "CATCH")
-
-/* Structure or union element. Value is offset in the structure. */
-__define_stab (N_SSYM, 0x60, "SSYM")
-
-/* Solaris2: Last stab emitted for module. */
-__define_stab (N_ENDM, 0x62, "ENDM")
-
-/* Name of main source file.
- Value is starting text address of the compilation.
- If multiple N_SO's appear, the first to contain a trailing / is the
- compilation directory. The first to not contain a trailing / is the
- source file name, relative to the compilation directory. Others (perhaps
- resulting from cfront) are ignored.
- On Solaris2, value is undefined, but desc is a source-language code. */
-
-__define_stab (N_SO, 0x64, "SO")
-
-/* Automatic variable in the stack. Value is offset from frame pointer.
- Also used for type descriptions. */
-__define_stab (N_LSYM, 0x80, "LSYM")
-
-/* Beginning of an include file. Only Sun uses this.
- In an object file, only the name is significant.
- The Sun linker puts data into some of the other fields. */
-__define_stab (N_BINCL, 0x82, "BINCL")
-
-/* Name of sub-source file (#include file).
- Value is starting text address of the compilation. */
-__define_stab (N_SOL, 0x84, "SOL")
-
-/* Parameter variable. Value is offset from argument pointer.
- (On most machines the argument pointer is the same as the frame pointer. */
-__define_stab (N_PSYM, 0xa0, "PSYM")
-
-/* End of an include file. No name.
- This and N_BINCL act as brackets around the file's output.
- In an object file, there is no significant data in this entry.
- The Sun linker puts data into some of the fields. */
-__define_stab (N_EINCL, 0xa2, "EINCL")
-
-/* Alternate entry point. Value is its address. */
-__define_stab (N_ENTRY, 0xa4, "ENTRY")
-
-/* Beginning of lexical block.
- The desc is the nesting level in lexical blocks.
- The value is the address of the start of the text for the block.
- The variables declared inside the block *precede* the N_LBRAC symbol.
- On Solaris2, the value is relative to the start of the current function. */
-__define_stab (N_LBRAC, 0xc0, "LBRAC")
-
-/* Place holder for deleted include file. Replaces a N_BINCL and everything
- up to the corresponding N_EINCL. The Sun linker generates these when
- it finds multiple identical copies of the symbols from an include file.
- This appears only in output from the Sun linker. */
-__define_stab (N_EXCL, 0xc2, "EXCL")
-
-/* Modula-2 scope information. Can someone say what info it contains? */
-__define_stab (N_SCOPE, 0xc4, "SCOPE")
-
-/* End of a lexical block. Desc matches the N_LBRAC's desc.
- The value is the address of the end of the text for the block.
- On Solaris2, the value is relative to the start of the current function. */
-__define_stab (N_RBRAC, 0xe0, "RBRAC")
-
-/* Begin named common block. Only the name is significant. */
-__define_stab (N_BCOMM, 0xe2, "BCOMM")
-
-/* End named common block. Only the name is significant
- (and it should match the N_BCOMM). */
-__define_stab (N_ECOMM, 0xe4, "ECOMM")
-
-/* Member of a common block; value is offset within the common block.
- This should occur within a BCOMM/ECOMM pair. */
-__define_stab (N_ECOML, 0xe8, "ECOML")
-
-/* Solaris2: Pascal "with" statement: type,,0,0,offset */
-__define_stab (N_WITH, 0xea, "WITH")
-
-/* These STAB's are used on Gould systems for Non-Base register symbols
- or something like that. FIXME. I have assigned the values at random
- since I don't have a Gould here. Fixups from Gould folk welcome... */
-__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
-__define_stab (N_NBDATA, 0xF2, "NBDATA")
-__define_stab (N_NBBSS, 0xF4, "NBBSS")
-__define_stab (N_NBSTS, 0xF6, "NBSTS")
-__define_stab (N_NBLCS, 0xF8, "NBLCS")
-
-/* Second symbol entry containing a length-value for the preceding entry.
- The value is the length. */
-__define_stab (N_LENG, 0xfe, "LENG")
-
-/* The above information, in matrix format.
-
- STAB MATRIX
- _________________________________________________
- | 00 - 1F are not dbx stab symbols |
- | In most cases, the low bit is the EXTernal bit|
-
- | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
- | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
-
- | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
- | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
-
- | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
- | 11 WEAKB | 13 | 15 | 17 |
-
- | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
- | 19 | 1B | 1D | 1F FN |
-
- |_______________________________________________|
- | Debug entries with bit 01 set are unused. |
- | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
- | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
- | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
- | 38 OBJ | 3A | 3C OPT | 3E |
- | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
- | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
- | 50 EHDECL*| 52 | 54 CATCH | 56 |
- | 58 | 5A | 5C | 5E |
- | 60 SSYM | 62 ENDM | 64 SO | 66 |
- | 68 | 6A | 6C | 6E |
- | 70 | 72 | 74 | 76 |
- | 78 | 7A | 7C | 7E |
- | 80 LSYM | 82 BINCL | 84 SOL | 86 |
- | 88 | 8A | 8C | 8E |
- | 90 | 92 | 94 | 96 |
- | 98 | 9A | 9C | 9E |
- | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
- | A8 | AA | AC | AE |
- | B0 | B2 | B4 | B6 |
- | B8 | BA | BC | BE |
- | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
- | C8 | CA | CC | CE |
- | D0 | D2 | D4 | D6 |
- | D8 | DA | DC | DE |
- | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
- | E8 ECOML | EA WITH | EC | EE |
- | F0 | F2 | F4 | F6 |
- | F8 | FA | FC | FE LENG |
- +-----------------------------------------------+
- * 50 EHDECL is also MOD2.
- * 48 BSLINE is also BROWS.
- */
diff --git a/pstack/aout/stab_gnu.h b/pstack/aout/stab_gnu.h
deleted file mode 100644
index 7d18e14a263..00000000000
--- a/pstack/aout/stab_gnu.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __GNU_STAB__
-
-/* Indicate the GNU stab.h is in use. */
-
-#define __GNU_STAB__
-
-#define __define_stab(NAME, CODE, STRING) NAME=CODE,
-#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
-
-enum __stab_debug_code
-{
-#include "aout/stab.def"
-LAST_UNUSED_STAB_CODE
-};
-
-#undef __define_stab
-
-/* Definitions of "desc" field for N_SO stabs in Solaris2. */
-
-#define N_SO_AS 1
-#define N_SO_C 2
-#define N_SO_ANSI_C 3
-#define N_SO_CC 4 /* C++ */
-#define N_SO_FORTRAN 5
-#define N_SO_PASCAL 6
-
-/* Solaris2: Floating point type values in basic types. */
-
-#define NF_NONE 0
-#define NF_SINGLE 1 /* IEEE 32-bit */
-#define NF_DOUBLE 2 /* IEEE 64-bit */
-#define NF_COMPLEX 3 /* Fortran complex */
-#define NF_COMPLEX16 4 /* Fortran double complex */
-#define NF_COMPLEX32 5 /* Fortran complex*16 */
-#define NF_LDOUBLE 6 /* Long double (whatever that is) */
-
-#endif /* __GNU_STAB_ */
diff --git a/pstack/bucomm.c b/pstack/bucomm.c
deleted file mode 100644
index d3231e71747..00000000000
--- a/pstack/bucomm.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* bucomm.c -- Bin Utils COMmon code.
- Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* We might put this in a library someday so it could be dynamically
- loaded, but for now it's not necessary. */
-
-#include <bfd.h>
-#include <libiberty.h>
-#include "bucomm.h"
-
-#include <sys/stat.h>
-#include <time.h> /* ctime, maybe time_t */
-
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-/* Error reporting */
-
-char *program_name;
-
-void
-bfd_nonfatal (string)
- CONST char *string;
-{
- CONST char *errmsg = bfd_errmsg (bfd_get_error ());
-
- if (string)
- fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
- else
- fprintf (stderr, "%s: %s\n", program_name, errmsg);
-}
-
-void
-bfd_fatal (string)
- CONST char *string;
-{
- bfd_nonfatal (string);
- xexit (1);
-}
-
-#ifdef ANSI_PROTOTYPES
-void
-fatal (const char *format, ...)
-{
- va_list args;
-
- fprintf (stderr, "%s: ", program_name);
- va_start (args, format);
- vfprintf (stderr, format, args);
- va_end (args);
- putc ('\n', stderr);
- xexit (1);
-}
-#else
-void
-fatal (va_alist)
- va_dcl
-{
- char *Format;
- va_list args;
-
- fprintf (stderr, "%s: ", program_name);
- va_start (args);
- Format = va_arg (args, char *);
- vfprintf (stderr, Format, args);
- va_end (args);
- putc ('\n', stderr);
- xexit (1);
-}
-#endif
-
-/* Set the default BFD target based on the configured target. Doing
- this permits the binutils to be configured for a particular target,
- and linked against a shared BFD library which was configured for a
- different target. */
-
-#define TARGET "elf32-i386" /* FIXME: hard-coded! */
-void
-set_default_bfd_target ()
-{
- /* The macro TARGET is defined by Makefile. */
- const char *target = TARGET;
-
- if (! bfd_set_default_target (target))
- {
- char *errmsg;
-
- errmsg = (char *) xmalloc (100 + strlen (target));
- sprintf (errmsg, "can't set BFD default target to `%s'", target);
- bfd_fatal (errmsg);
- }
-}
-
-/* After a false return from bfd_check_format_matches with
- bfd_get_error () == bfd_error_file_ambiguously_recognized, print
- the possible matching targets. */
-
-void
-list_matching_formats (p)
- char **p;
-{
- fprintf(stderr, "%s: Matching formats:", program_name);
- while (*p)
- fprintf(stderr, " %s", *p++);
- fprintf(stderr, "\n");
-}
-
-/* List the supported targets. */
-
-void
-list_supported_targets (name, f)
- const char *name;
- FILE *f;
-{
- extern bfd_target *bfd_target_vector[];
- int t;
-
- if (name == NULL)
- fprintf (f, "Supported targets:");
- else
- fprintf (f, "%s: supported targets:", name);
- for (t = 0; bfd_target_vector[t] != NULL; t++)
- fprintf (f, " %s", bfd_target_vector[t]->name);
- fprintf (f, "\n");
-}
-
-/* Display the archive header for an element as if it were an ls -l listing:
-
- Mode User\tGroup\tSize\tDate Name */
-
-void
-print_arelt_descr (file, abfd, verbose)
- FILE *file;
- bfd *abfd;
- boolean verbose;
-{
- struct stat buf;
-
- if (verbose)
- {
- if (bfd_stat_arch_elt (abfd, &buf) == 0)
- {
- char modebuf[11];
- char timebuf[40];
- time_t when = buf.st_mtime;
- CONST char *ctime_result = (CONST char *) ctime (&when);
-
- /* POSIX format: skip weekday and seconds from ctime output. */
- sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
-
- mode_string (buf.st_mode, modebuf);
- modebuf[10] = '\0';
- /* POSIX 1003.2/D11 says to skip first character (entry type). */
- fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
- (long) buf.st_uid, (long) buf.st_gid,
- (long) buf.st_size, timebuf);
- }
- }
-
- fprintf (file, "%s\n", bfd_get_filename (abfd));
-}
-
-/* Return the name of a temporary file in the same directory as FILENAME. */
-
-char *
-make_tempname (filename)
- char *filename;
-{
- static char template[] = "stXXXXXX";
- char *tmpname;
- char *slash = strrchr (filename, '/');
-
-#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32)
- if (slash == NULL)
- slash = strrchr (filename, '\\');
-#endif
-
- if (slash != (char *) NULL)
- {
- char c;
-
- c = *slash;
- *slash = 0;
- tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
- strcpy (tmpname, filename);
- strcat (tmpname, "/");
- strcat (tmpname, template);
- mkstemp (tmpname);
- *slash = c;
- }
- else
- {
- tmpname = xmalloc (sizeof (template));
- strcpy (tmpname, template);
- mkstemp (tmpname);
- }
- return tmpname;
-}
-
-/* Parse a string into a VMA, with a fatal error if it can't be
- parsed. */
-
-bfd_vma
-parse_vma (s, arg)
- const char *s;
- const char *arg;
-{
- bfd_vma ret;
- const char *end;
-
- ret = bfd_scan_vma (s, &end, 0);
- if (*end != '\0')
- {
- fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s);
- exit (1);
- }
- return ret;
-}
diff --git a/pstack/bucomm.h b/pstack/bucomm.h
deleted file mode 100644
index 6b3633d8d63..00000000000
--- a/pstack/bucomm.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* bucomm.h -- binutils common include file.
- Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU Binutils.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _BUCOMM_H
-#define _BUCOMM_H
-
-#include "ansidecl.h"
-#include <stdio.h>
-#include <sys/types.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <string.h>
-
-#include <stdlib.h>
-
-#include <fcntl.h>
-
-#ifdef __GNUC__
-# undef alloca
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-# if !defined (__STDC__) && !defined (__hpux)
-char *alloca ();
-# else
-void *alloca ();
-# endif /* __STDC__, __hpux */
-# endif /* alloca */
-# endif /* HAVE_ALLOCA_H */
-#endif
-
-#ifndef BFD_TRUE_FALSE
-#define boolean bfd_boolean
-#define true TRUE
-#define false FALSE
-#endif
-
-/* bucomm.c */
-void bfd_nonfatal PARAMS ((CONST char *));
-
-void bfd_fatal PARAMS ((CONST char *));
-
-void fatal PARAMS ((CONST char *, ...));
-
-void set_default_bfd_target PARAMS ((void));
-
-void list_matching_formats PARAMS ((char **p));
-
-void list_supported_targets PARAMS ((const char *, FILE *));
-
-void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose));
-
-char *make_tempname PARAMS ((char *));
-
-bfd_vma parse_vma PARAMS ((const char *, const char *));
-
-extern char *program_name;
-
-/* filemode.c */
-void mode_string PARAMS ((unsigned long mode, char *buf));
-
-/* version.c */
-extern void print_version PARAMS ((const char *));
-
-/* libiberty */
-PTR xmalloc PARAMS ((size_t));
-
-PTR xrealloc PARAMS ((PTR, size_t));
-
-#endif /* _BUCOMM_H */
diff --git a/pstack/budbg.h b/pstack/budbg.h
deleted file mode 100644
index 9f0203ad5e7..00000000000
--- a/pstack/budbg.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* budbg.c -- Interfaces to the generic debugging information routines.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#ifndef BUDBG_H
-#define BUDBG_H
-
-#include <stdio.h>
-
-#ifndef BFD_TRUE_FALSE
-#define boolean bfd_boolean
-#define true TRUE
-#define false FALSE
-#endif
-
-/* Routine used to read generic debugging information. */
-
-extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long));
-
-/* Routine used to print generic debugging information. */
-
-extern boolean print_debugging_info PARAMS ((FILE *, PTR));
-
-/* Routines used to read and write stabs information. */
-
-extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long));
-
-extern boolean finish_stab PARAMS ((PTR, PTR));
-
-extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *));
-
-extern boolean write_stabs_in_sections_debugging_info
- PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **,
- bfd_size_type *));
-
-/* Routines used to read and write IEEE debugging information. */
-
-extern boolean parse_ieee
- PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type));
-
-extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR));
-
-/* Routine used to read COFF debugging information. */
-
-extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR));
-
-#endif
diff --git a/pstack/debug.c b/pstack/debug.c
deleted file mode 100644
index 73412ae3f03..00000000000
--- a/pstack/debug.c
+++ /dev/null
@@ -1,3509 +0,0 @@
-/* debug.c -- Handle generic debugging information.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file implements a generic debugging format. We may eventually
- have readers which convert different formats into this generic
- format, and writers which write it out. The initial impetus for
- this was writing a convertor from stabs to HP IEEE-695 debugging
- format. */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <bfd.h>
-#include "bucomm.h"
-#include <libiberty.h>
-#include "debug.h"
-
-/* Global information we keep for debugging. A pointer to this
- structure is the debugging handle passed to all the routines. */
-
-struct debug_handle
-{
- /* A linked list of compilation units. */
- struct debug_unit *units;
- /* The current compilation unit. */
- struct debug_unit *current_unit;
- /* The current source file. */
- struct debug_file *current_file;
- /* The current function. */
- struct debug_function *current_function;
- /* The current block. */
- struct debug_block *current_block;
- /* The current line number information for the current unit. */
- struct debug_lineno *current_lineno;
- /* Mark. This is used by debug_write. */
- unsigned int mark;
- /* A struct/class ID used by debug_write. */
- unsigned int class_id;
- /* The base for class_id for this call to debug_write. */
- unsigned int base_id;
- /* The current line number in debug_write. */
- struct debug_lineno *current_write_lineno;
- unsigned int current_write_lineno_index;
- /* A list of classes which have assigned ID's during debug_write.
- This is linked through the next_id field of debug_class_type. */
- struct debug_class_id *id_list;
- /* A list used to avoid recursion during debug_type_samep. */
- struct debug_type_compare_list *compare_list;
-};
-
-/* Information we keep for a single compilation unit. */
-
-struct debug_unit
-{
- /* The next compilation unit. */
- struct debug_unit *next;
- /* A list of files included in this compilation unit. The first
- file is always the main one, and that is where the main file name
- is stored. */
- struct debug_file *files;
- /* Line number information for this compilation unit. This is not
- stored by function, because assembler code may have line number
- information without function information. */
- struct debug_lineno *linenos;
-};
-
-/* Information kept for a single source file. */
-
-struct debug_file
-{
- /* The next source file in this compilation unit. */
- struct debug_file *next;
- /* The name of the source file. */
- const char *filename;
- /* Global functions, variables, types, etc. */
- struct debug_namespace *globals;
-};
-
-/* A type. */
-
-struct debug_type
-{
- /* Kind of type. */
- enum debug_type_kind kind;
- /* Size of type (0 if not known). */
- unsigned int size;
- /* Type which is a pointer to this type. */
- debug_type pointer;
- /* Tagged union with additional information about the type. */
- union
- {
- /* DEBUG_KIND_INDIRECT. */
- struct debug_indirect_type *kindirect;
- /* DEBUG_KIND_INT. */
- /* Whether the integer is unsigned. */
- boolean kint;
- /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
- DEBUG_KIND_UNION_CLASS. */
- struct debug_class_type *kclass;
- /* DEBUG_KIND_ENUM. */
- struct debug_enum_type *kenum;
- /* DEBUG_KIND_POINTER. */
- struct debug_type *kpointer;
- /* DEBUG_KIND_FUNCTION. */
- struct debug_function_type *kfunction;
- /* DEBUG_KIND_REFERENCE. */
- struct debug_type *kreference;
- /* DEBUG_KIND_RANGE. */
- struct debug_range_type *krange;
- /* DEBUG_KIND_ARRAY. */
- struct debug_array_type *karray;
- /* DEBUG_KIND_SET. */
- struct debug_set_type *kset;
- /* DEBUG_KIND_OFFSET. */
- struct debug_offset_type *koffset;
- /* DEBUG_KIND_METHOD. */
- struct debug_method_type *kmethod;
- /* DEBUG_KIND_CONST. */
- struct debug_type *kconst;
- /* DEBUG_KIND_VOLATILE. */
- struct debug_type *kvolatile;
- /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */
- struct debug_named_type *knamed;
- } u;
-};
-
-/* Information kept for an indirect type. */
-
-struct debug_indirect_type
-{
- /* Slot where the final type will appear. */
- debug_type *slot;
- /* Tag. */
- const char *tag;
-};
-
-/* Information kept for a struct, union, or class. */
-
-struct debug_class_type
-{
- /* NULL terminated array of fields. */
- debug_field *fields;
- /* A mark field which indicates whether the struct has already been
- printed. */
- unsigned int mark;
- /* This is used to uniquely identify unnamed structs when printing. */
- unsigned int id;
- /* The remaining fields are only used for DEBUG_KIND_CLASS and
- DEBUG_KIND_UNION_CLASS. */
- /* NULL terminated array of base classes. */
- debug_baseclass *baseclasses;
- /* NULL terminated array of methods. */
- debug_method *methods;
- /* The type of the class providing the virtual function table for
- this class. This may point to the type itself. */
- debug_type vptrbase;
-};
-
-/* Information kept for an enum. */
-
-struct debug_enum_type
-{
- /* NULL terminated array of names. */
- const char **names;
- /* Array of corresponding values. */
- bfd_signed_vma *values;
-};
-
-/* Information kept for a function. FIXME: We should be able to
- record the parameter types. */
-
-struct debug_function_type
-{
- /* Return type. */
- debug_type return_type;
- /* NULL terminated array of argument types. */
- debug_type *arg_types;
- /* Whether the function takes a variable number of arguments. */
- boolean varargs;
-};
-
-/* Information kept for a range. */
-
-struct debug_range_type
-{
- /* Range base type. */
- debug_type type;
- /* Lower bound. */
- bfd_signed_vma lower;
- /* Upper bound. */
- bfd_signed_vma upper;
-};
-
-/* Information kept for an array. */
-
-struct debug_array_type
-{
- /* Element type. */
- debug_type element_type;
- /* Range type. */
- debug_type range_type;
- /* Lower bound. */
- bfd_signed_vma lower;
- /* Upper bound. */
- bfd_signed_vma upper;
- /* Whether this array is really a string. */
- boolean stringp;
-};
-
-/* Information kept for a set. */
-
-struct debug_set_type
-{
- /* Base type. */
- debug_type type;
- /* Whether this set is really a bitstring. */
- boolean bitstringp;
-};
-
-/* Information kept for an offset type (a based pointer). */
-
-struct debug_offset_type
-{
- /* The type the pointer is an offset from. */
- debug_type base_type;
- /* The type the pointer points to. */
- debug_type target_type;
-};
-
-/* Information kept for a method type. */
-
-struct debug_method_type
-{
- /* The return type. */
- debug_type return_type;
- /* The object type which this method is for. */
- debug_type domain_type;
- /* A NULL terminated array of argument types. */
- debug_type *arg_types;
- /* Whether the method takes a variable number of arguments. */
- boolean varargs;
-};
-
-/* Information kept for a named type. */
-
-struct debug_named_type
-{
- /* Name. */
- struct debug_name *name;
- /* Real type. */
- debug_type type;
-};
-
-/* A field in a struct or union. */
-
-struct debug_field
-{
- /* Name of the field. */
- const char *name;
- /* Type of the field. */
- struct debug_type *type;
- /* Visibility of the field. */
- enum debug_visibility visibility;
- /* Whether this is a static member. */
- boolean static_member;
- union
- {
- /* If static_member is false. */
- struct
- {
- /* Bit position of the field in the struct. */
- unsigned int bitpos;
- /* Size of the field in bits. */
- unsigned int bitsize;
- } f;
- /* If static_member is true. */
- struct
- {
- const char *physname;
- } s;
- } u;
-};
-
-/* A base class for an object. */
-
-struct debug_baseclass
-{
- /* Type of the base class. */
- struct debug_type *type;
- /* Bit position of the base class in the object. */
- unsigned int bitpos;
- /* Whether the base class is virtual. */
- boolean virtual;
- /* Visibility of the base class. */
- enum debug_visibility visibility;
-};
-
-/* A method of an object. */
-
-struct debug_method
-{
- /* The name of the method. */
- const char *name;
- /* A NULL terminated array of different types of variants. */
- struct debug_method_variant **variants;
-};
-
-/* The variants of a method function of an object. These indicate
- which method to run. */
-
-struct debug_method_variant
-{
- /* The physical name of the function. */
- const char *physname;
- /* The type of the function. */
- struct debug_type *type;
- /* The visibility of the function. */
- enum debug_visibility visibility;
- /* Whether the function is const. */
- boolean constp;
- /* Whether the function is volatile. */
- boolean volatilep;
- /* The offset to the function in the virtual function table. */
- bfd_vma voffset;
- /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */
-#define VOFFSET_STATIC_METHOD ((bfd_vma) -1)
- /* Context of a virtual method function. */
- struct debug_type *context;
-};
-
-/* A variable. This is the information we keep for a variable object.
- This has no name; a name is associated with a variable in a
- debug_name structure. */
-
-struct debug_variable
-{
- /* Kind of variable. */
- enum debug_var_kind kind;
- /* Type. */
- debug_type type;
- /* Value. The interpretation of the value depends upon kind. */
- bfd_vma val;
-};
-
-/* A function. This has no name; a name is associated with a function
- in a debug_name structure. */
-
-struct debug_function
-{
- /* Return type. */
- debug_type return_type;
- /* Parameter information. */
- struct debug_parameter *parameters;
- /* Block information. The first structure on the list is the main
- block of the function, and describes function local variables. */
- struct debug_block *blocks;
-};
-
-/* A function parameter. */
-
-struct debug_parameter
-{
- /* Next parameter. */
- struct debug_parameter *next;
- /* Name. */
- const char *name;
- /* Type. */
- debug_type type;
- /* Kind. */
- enum debug_parm_kind kind;
- /* Value (meaning depends upon kind). */
- bfd_vma val;
-};
-
-/* A typed constant. */
-
-struct debug_typed_constant
-{
- /* Type. */
- debug_type type;
- /* Value. FIXME: We may eventually need to support non-integral
- values. */
- bfd_vma val;
-};
-
-/* Information about a block within a function. */
-
-struct debug_block
-{
- /* Next block with the same parent. */
- struct debug_block *next;
- /* Parent block. */
- struct debug_block *parent;
- /* List of child blocks. */
- struct debug_block *children;
- /* Start address of the block. */
- bfd_vma start;
- /* End address of the block. */
- bfd_vma end;
- /* Local variables. */
- struct debug_namespace *locals;
-};
-
-/* Line number information we keep for a compilation unit. FIXME:
- This structure is easy to create, but can be very space
- inefficient. */
-
-struct debug_lineno
-{
- /* More line number information for this block. */
- struct debug_lineno *next;
- /* Source file. */
- struct debug_file *file;
- /* Line numbers, terminated by a -1 or the end of the array. */
-#define DEBUG_LINENO_COUNT 10
- unsigned long linenos[DEBUG_LINENO_COUNT];
- /* Addresses for the line numbers. */
- bfd_vma addrs[DEBUG_LINENO_COUNT];
-};
-
-/* A namespace. This is a mapping from names to objects. FIXME: This
- should be implemented as a hash table. */
-
-struct debug_namespace
-{
- /* List of items in this namespace. */
- struct debug_name *list;
- /* Pointer to where the next item in this namespace should go. */
- struct debug_name **tail;
-};
-
-/* Kinds of objects that appear in a namespace. */
-
-enum debug_object_kind
-{
- /* A type. */
- DEBUG_OBJECT_TYPE,
- /* A tagged type (really a different sort of namespace). */
- DEBUG_OBJECT_TAG,
- /* A variable. */
- DEBUG_OBJECT_VARIABLE,
- /* A function. */
- DEBUG_OBJECT_FUNCTION,
- /* An integer constant. */
- DEBUG_OBJECT_INT_CONSTANT,
- /* A floating point constant. */
- DEBUG_OBJECT_FLOAT_CONSTANT,
- /* A typed constant. */
- DEBUG_OBJECT_TYPED_CONSTANT
-};
-
-/* Linkage of an object that appears in a namespace. */
-
-enum debug_object_linkage
-{
- /* Local variable. */
- DEBUG_LINKAGE_AUTOMATIC,
- /* Static--either file static or function static, depending upon the
- namespace is. */
- DEBUG_LINKAGE_STATIC,
- /* Global. */
- DEBUG_LINKAGE_GLOBAL,
- /* No linkage. */
- DEBUG_LINKAGE_NONE
-};
-
-/* A name in a namespace. */
-
-struct debug_name
-{
- /* Next name in this namespace. */
- struct debug_name *next;
- /* Name. */
- const char *name;
- /* Mark. This is used by debug_write. */
- unsigned int mark;
- /* Kind of object. */
- enum debug_object_kind kind;
- /* Linkage of object. */
- enum debug_object_linkage linkage;
- /* Tagged union with additional information about the object. */
- union
- {
- /* DEBUG_OBJECT_TYPE. */
- struct debug_type *type;
- /* DEBUG_OBJECT_TAG. */
- struct debug_type *tag;
- /* DEBUG_OBJECT_VARIABLE. */
- struct debug_variable *variable;
- /* DEBUG_OBJECT_FUNCTION. */
- struct debug_function *function;
- /* DEBUG_OBJECT_INT_CONSTANT. */
- bfd_vma int_constant;
- /* DEBUG_OBJECT_FLOAT_CONSTANT. */
- double float_constant;
- /* DEBUG_OBJECT_TYPED_CONSTANT. */
- struct debug_typed_constant *typed_constant;
- } u;
-};
-
-/* During debug_write, a linked list of these structures is used to
- keep track of ID numbers that have been assigned to classes. */
-
-struct debug_class_id
-{
- /* Next ID number. */
- struct debug_class_id *next;
- /* The type with the ID. */
- struct debug_type *type;
- /* The tag; NULL if no tag. */
- const char *tag;
-};
-
-/* During debug_type_samep, a linked list of these structures is kept
- on the stack to avoid infinite recursion. */
-
-struct debug_type_compare_list
-{
- /* Next type on list. */
- struct debug_type_compare_list *next;
- /* The types we are comparing. */
- struct debug_type *t1;
- struct debug_type *t2;
-};
-
-/* Local functions. */
-
-static void debug_error PARAMS ((const char *));
-static struct debug_name *debug_add_to_namespace
- PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
- enum debug_object_kind, enum debug_object_linkage));
-static struct debug_name *debug_add_to_current_namespace
- PARAMS ((struct debug_handle *, const char *, enum debug_object_kind,
- enum debug_object_linkage));
-static struct debug_type *debug_make_type
- PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
-static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type));
-static boolean debug_write_name
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_name *));
-static boolean debug_write_type
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_type *, struct debug_name *));
-static boolean debug_write_class_type
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_type *, const char *));
-static boolean debug_write_function
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- const char *, enum debug_object_linkage, struct debug_function *));
-static boolean debug_write_block
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_block *));
-static boolean debug_write_linenos
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- bfd_vma));
-static boolean debug_set_class_id
- PARAMS ((struct debug_handle *, const char *, struct debug_type *));
-static boolean debug_type_samep
- PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
-static boolean debug_class_type_samep
- PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
-
-/* Issue an error message. */
-
-static void
-debug_error (message)
- const char *message;
-{
- fprintf (stderr, "%s\n", message);
-}
-
-/* Add an object to a namespace. */
-
-static struct debug_name *
-debug_add_to_namespace (info, nsp, name, kind, linkage)
- struct debug_handle *info;
- struct debug_namespace **nsp;
- const char *name;
- enum debug_object_kind kind;
- enum debug_object_linkage linkage;
-{
- struct debug_name *n;
- struct debug_namespace *ns;
-
- n = (struct debug_name *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->name = name;
- n->kind = kind;
- n->linkage = linkage;
-
- ns = *nsp;
- if (ns == NULL)
- {
- ns = (struct debug_namespace *) xmalloc (sizeof *ns);
- memset (ns, 0, sizeof *ns);
-
- ns->tail = &ns->list;
-
- *nsp = ns;
- }
-
- *ns->tail = n;
- ns->tail = &n->next;
-
- return n;
-}
-
-/* Add an object to the current namespace. */
-
-static struct debug_name *
-debug_add_to_current_namespace (info, name, kind, linkage)
- struct debug_handle *info;
- const char *name;
- enum debug_object_kind kind;
- enum debug_object_linkage linkage;
-{
- struct debug_namespace **nsp;
-
- if (info->current_unit == NULL
- || info->current_file == NULL)
- {
- debug_error ("debug_add_to_current_namespace: no current file");
- return NULL;
- }
-
- if (info->current_block != NULL)
- nsp = &info->current_block->locals;
- else
- nsp = &info->current_file->globals;
-
- return debug_add_to_namespace (info, nsp, name, kind, linkage);
-}
-
-/* Return a handle for debugging information. */
-
-PTR
-debug_init ()
-{
- struct debug_handle *ret;
-
- ret = (struct debug_handle *) xmalloc (sizeof *ret);
- memset (ret, 0, sizeof *ret);
- return (PTR) ret;
-}
-
-/* Set the source filename. This implicitly starts a new compilation
- unit. */
-
-boolean
-debug_set_filename (handle, name)
- PTR handle;
- const char *name;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_file *nfile;
- struct debug_unit *nunit;
-
- if (name == NULL)
- name = "";
-
- nfile = (struct debug_file *) xmalloc (sizeof *nfile);
- memset (nfile, 0, sizeof *nfile);
-
- nfile->filename = name;
-
- nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
- memset (nunit, 0, sizeof *nunit);
-
- nunit->files = nfile;
- info->current_file = nfile;
-
- if (info->current_unit != NULL)
- info->current_unit->next = nunit;
- else
- {
- assert (info->units == NULL);
- info->units = nunit;
- }
-
- info->current_unit = nunit;
-
- info->current_function = NULL;
- info->current_block = NULL;
- info->current_lineno = NULL;
-
- return true;
-}
-
-/* Change source files to the given file name. This is used for
- include files in a single compilation unit. */
-
-boolean
-debug_start_source (handle, name)
- PTR handle;
- const char *name;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_file *f, **pf;
-
- if (name == NULL)
- name = "";
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_start_source: no debug_set_filename call");
- return false;
- }
-
- for (f = info->current_unit->files; f != NULL; f = f->next)
- {
- if (f->filename[0] == name[0]
- && f->filename[1] == name[1]
- && strcmp (f->filename, name) == 0)
- {
- info->current_file = f;
- return true;
- }
- }
-
- f = (struct debug_file *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->filename = name;
-
- for (pf = &info->current_file->next;
- *pf != NULL;
- pf = &(*pf)->next)
- ;
- *pf = f;
-
- info->current_file = f;
-
- return true;
-}
-
-/* Record a function definition. This implicitly starts a function
- block. The debug_type argument is the type of the return value.
- The boolean indicates whether the function is globally visible.
- The bfd_vma is the address of the start of the function. Currently
- the parameter types are specified by calls to
- debug_record_parameter. FIXME: There is no way to specify nested
- functions. */
-
-boolean
-debug_record_function (handle, name, return_type, global, addr)
- PTR handle;
- const char *name;
- debug_type return_type;
- boolean global;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_function *f;
- struct debug_block *b;
- struct debug_name *n;
-
- if (name == NULL)
- name = "";
- if (return_type == NULL)
- return false;
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_record_function: no debug_set_filename call");
- return false;
- }
-
- f = (struct debug_function *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->return_type = return_type;
-
- b = (struct debug_block *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
-
- b->start = addr;
- b->end = (bfd_vma) -1;
-
- f->blocks = b;
-
- info->current_function = f;
- info->current_block = b;
-
- /* FIXME: If we could handle nested functions, this would be the
- place: we would want to use a different namespace. */
- n = debug_add_to_namespace (info,
- &info->current_file->globals,
- name,
- DEBUG_OBJECT_FUNCTION,
- (global
- ? DEBUG_LINKAGE_GLOBAL
- : DEBUG_LINKAGE_STATIC));
- if (n == NULL)
- return false;
-
- n->u.function = f;
-
- return true;
-}
-
-/* Record a parameter for the current function. */
-
-boolean
-debug_record_parameter (handle, name, type, kind, val)
- PTR handle;
- const char *name;
- debug_type type;
- enum debug_parm_kind kind;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_parameter *p, **pp;
-
- if (name == NULL || type == NULL)
- return false;
-
- if (info->current_unit == NULL
- || info->current_function == NULL)
- {
- debug_error ("debug_record_parameter: no current function");
- return false;
- }
-
- p = (struct debug_parameter *) xmalloc (sizeof *p);
- memset (p, 0, sizeof *p);
-
- p->name = name;
- p->type = type;
- p->kind = kind;
- p->val = val;
-
- for (pp = &info->current_function->parameters;
- *pp != NULL;
- pp = &(*pp)->next)
- ;
- *pp = p;
-
- return true;
-}
-
-/* End a function. FIXME: This should handle function nesting. */
-
-boolean
-debug_end_function (handle, addr)
- PTR handle;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- if (info->current_unit == NULL
- || info->current_block == NULL
- || info->current_function == NULL)
- {
- debug_error ("debug_end_function: no current function");
- return false;
- }
-
- if (info->current_block->parent != NULL)
- {
- debug_error ("debug_end_function: some blocks were not closed");
- return false;
- }
-
- info->current_block->end = addr;
-
- info->current_function = NULL;
- info->current_block = NULL;
-
- return true;
-}
-
-/* Start a block in a function. All local information will be
- recorded in this block, until the matching call to debug_end_block.
- debug_start_block and debug_end_block may be nested. The bfd_vma
- argument is the address at which this block starts. */
-
-boolean
-debug_start_block (handle, addr)
- PTR handle;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_block *b, **pb;
-
- /* We must always have a current block: debug_record_function sets
- one up. */
- if (info->current_unit == NULL
- || info->current_block == NULL)
- {
- debug_error ("debug_start_block: no current block");
- return false;
- }
-
- b = (struct debug_block *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
-
- b->parent = info->current_block;
- b->start = addr;
- b->end = (bfd_vma) -1;
-
- /* This new block is a child of the current block. */
- for (pb = &info->current_block->children;
- *pb != NULL;
- pb = &(*pb)->next)
- ;
- *pb = b;
-
- info->current_block = b;
-
- return true;
-}
-
-/* Finish a block in a function. This matches the call to
- debug_start_block. The argument is the address at which this block
- ends. */
-
-boolean
-debug_end_block (handle, addr)
- PTR handle;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_block *parent;
-
- if (info->current_unit == NULL
- || info->current_block == NULL)
- {
- debug_error ("debug_end_block: no current block");
- return false;
- }
-
- parent = info->current_block->parent;
- if (parent == NULL)
- {
- debug_error ("debug_end_block: attempt to close top level block");
- return false;
- }
-
- info->current_block->end = addr;
-
- info->current_block = parent;
-
- return true;
-}
-
-/* Associate a line number in the current source file and function
- with a given address. */
-
-boolean
-debug_record_line (handle, lineno, addr)
- PTR handle;
- unsigned long lineno;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_lineno *l;
- unsigned int i;
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_record_line: no current unit");
- return false;
- }
-
- l = info->current_lineno;
- if (l != NULL && l->file == info->current_file)
- {
- for (i = 0; i < DEBUG_LINENO_COUNT; i++)
- {
- if (l->linenos[i] == (unsigned long) -1)
- {
- l->linenos[i] = lineno;
- l->addrs[i] = addr;
- return true;
- }
- }
- }
-
- /* If we get here, then either 1) there is no current_lineno
- structure, which means this is the first line number in this
- compilation unit, 2) the current_lineno structure is for a
- different file, or 3) the current_lineno structure is full.
- Regardless, we want to allocate a new debug_lineno structure, put
- it in the right place, and make it the new current_lineno
- structure. */
-
- l = (struct debug_lineno *) xmalloc (sizeof *l);
- memset (l, 0, sizeof *l);
-
- l->file = info->current_file;
- l->linenos[0] = lineno;
- l->addrs[0] = addr;
- for (i = 1; i < DEBUG_LINENO_COUNT; i++)
- l->linenos[i] = (unsigned long) -1;
-
- if (info->current_lineno != NULL)
- info->current_lineno->next = l;
- else
- info->current_unit->linenos = l;
-
- info->current_lineno = l;
-
- return true;
-}
-
-/* Start a named common block. This is a block of variables that may
- move in memory. */
-
-boolean
-debug_start_common_block (handle, name)
- PTR handle;
- const char *name;
-{
- /* FIXME */
- debug_error ("debug_start_common_block: not implemented");
- return false;
-}
-
-/* End a named common block. */
-
-boolean
-debug_end_common_block (handle, name)
- PTR handle;
- const char *name;
-{
- /* FIXME */
- debug_error ("debug_end_common_block: not implemented");
- return false;
-}
-
-/* Record a named integer constant. */
-
-boolean
-debug_record_int_const (handle, name, val)
- PTR handle;
- const char *name;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_name *n;
-
- if (name == NULL)
- return false;
-
- n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
- DEBUG_LINKAGE_NONE);
- if (n == NULL)
- return false;
-
- n->u.int_constant = val;
-
- return true;
-}
-
-/* Record a named floating point constant. */
-
-boolean
-debug_record_float_const (handle, name, val)
- PTR handle;
- const char *name;
- double val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_name *n;
-
- if (name == NULL)
- return false;
-
- n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
- DEBUG_LINKAGE_NONE);
- if (n == NULL)
- return false;
-
- n->u.float_constant = val;
-
- return true;
-}
-
-/* Record a typed constant with an integral value. */
-
-boolean
-debug_record_typed_const (handle, name, type, val)
- PTR handle;
- const char *name;
- debug_type type;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_name *n;
- struct debug_typed_constant *tc;
-
- if (name == NULL || type == NULL)
- return false;
-
- n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
- DEBUG_LINKAGE_NONE);
- if (n == NULL)
- return false;
-
- tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
- memset (tc, 0, sizeof *tc);
-
- tc->type = type;
- tc->val = val;
-
- n->u.typed_constant = tc;
-
- return true;
-}
-
-/* Record a label. */
-
-boolean
-debug_record_label (handle, name, type, addr)
- PTR handle;
- const char *name;
- debug_type type;
- bfd_vma addr;
-{
- /* FIXME. */
- debug_error ("debug_record_label not implemented");
- return false;
-}
-
-/* Record a variable. */
-
-boolean
-debug_record_variable (handle, name, type, kind, val)
- PTR handle;
- const char *name;
- debug_type type;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_namespace **nsp;
- enum debug_object_linkage linkage;
- struct debug_name *n;
- struct debug_variable *v;
-
- if (name == NULL || type == NULL)
- return false;
-
- if (info->current_unit == NULL
- || info->current_file == NULL)
- {
- debug_error ("debug_record_variable: no current file");
- return false;
- }
-
- if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
- {
- nsp = &info->current_file->globals;
- if (kind == DEBUG_GLOBAL)
- linkage = DEBUG_LINKAGE_GLOBAL;
- else
- linkage = DEBUG_LINKAGE_STATIC;
- }
- else
- {
- if (info->current_block == NULL)
- {
- debug_error ("debug_record_variable: no current block");
- return false;
- }
- nsp = &info->current_block->locals;
- linkage = DEBUG_LINKAGE_AUTOMATIC;
- }
-
- n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
- if (n == NULL)
- return false;
-
- v = (struct debug_variable *) xmalloc (sizeof *v);
- memset (v, 0, sizeof *v);
-
- v->kind = kind;
- v->type = type;
- v->val = val;
-
- n->u.variable = v;
-
- return true;
-}
-
-/* Make a type with a given kind and size. */
-
-/*ARGSUSED*/
-static struct debug_type *
-debug_make_type (info, kind, size)
- struct debug_handle *info;
- enum debug_type_kind kind;
- unsigned int size;
-{
- struct debug_type *t;
-
- t = (struct debug_type *) xmalloc (sizeof *t);
- memset (t, 0, sizeof *t);
-
- t->kind = kind;
- t->size = size;
-
- return t;
-}
-
-/* Make an indirect type which may be used as a placeholder for a type
- which is referenced before it is defined. */
-
-debug_type
-debug_make_indirect_type (handle, slot, tag)
- PTR handle;
- debug_type *slot;
- const char *tag;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_indirect_type *i;
-
- t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- i = (struct debug_indirect_type *) xmalloc (sizeof *i);
- memset (i, 0, sizeof *i);
-
- i->slot = slot;
- i->tag = tag;
-
- t->u.kindirect = i;
-
- return t;
-}
-
-/* Make a void type. There is only one of these. */
-
-debug_type
-debug_make_void_type (handle)
- PTR handle;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_VOID, 0);
-}
-
-/* Make an integer type of a given size. The boolean argument is true
- if the integer is unsigned. */
-
-debug_type
-debug_make_int_type (handle, size, unsignedp)
- PTR handle;
- unsigned int size;
- boolean unsignedp;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- t = debug_make_type (info, DEBUG_KIND_INT, size);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kint = unsignedp;
-
- return t;
-}
-
-/* Make a floating point type of a given size. FIXME: On some
- platforms, like an Alpha, you probably need to be able to specify
- the format. */
-
-debug_type
-debug_make_float_type (handle, size)
- PTR handle;
- unsigned int size;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_FLOAT, size);
-}
-
-/* Make a boolean type of a given size. */
-
-debug_type
-debug_make_bool_type (handle, size)
- PTR handle;
- unsigned int size;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_BOOL, size);
-}
-
-/* Make a complex type of a given size. */
-
-debug_type
-debug_make_complex_type (handle, size)
- PTR handle;
- unsigned int size;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
-}
-
-/* Make a structure type. The second argument is true for a struct,
- false for a union. The third argument is the size of the struct.
- The fourth argument is a NULL terminated array of fields. */
-
-debug_type
-debug_make_struct_type (handle, structp, size, fields)
- PTR handle;
- boolean structp;
- bfd_vma size;
- debug_field *fields;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_class_type *c;
-
- t = debug_make_type (info,
- structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
- size);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- c = (struct debug_class_type *) xmalloc (sizeof *c);
- memset (c, 0, sizeof *c);
-
- c->fields = fields;
-
- t->u.kclass = c;
-
- return t;
-}
-
-/* Make an object type. The first three arguments after the handle
- are the same as for debug_make_struct_type. The next arguments are
- a NULL terminated array of base classes, a NULL terminated array of
- methods, the type of the object holding the virtual function table
- if it is not this object, and a boolean which is true if this
- object has its own virtual function table. */
-
-debug_type
-debug_make_object_type (handle, structp, size, fields, baseclasses,
- methods, vptrbase, ownvptr)
- PTR handle;
- boolean structp;
- bfd_vma size;
- debug_field *fields;
- debug_baseclass *baseclasses;
- debug_method *methods;
- debug_type vptrbase;
- boolean ownvptr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_class_type *c;
-
- t = debug_make_type (info,
- structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
- size);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- c = (struct debug_class_type *) xmalloc (sizeof *c);
- memset (c, 0, sizeof *c);
-
- c->fields = fields;
- c->baseclasses = baseclasses;
- c->methods = methods;
- if (ownvptr)
- c->vptrbase = t;
- else
- c->vptrbase = vptrbase;
-
- t->u.kclass = c;
-
- return t;
-}
-
-/* Make an enumeration type. The arguments are a null terminated
- array of strings, and an array of corresponding values. */
-
-debug_type
-debug_make_enum_type (handle, names, values)
- PTR handle;
- const char **names;
- bfd_signed_vma *values;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_enum_type *e;
-
- t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- e = (struct debug_enum_type *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
-
- e->names = names;
- e->values = values;
-
- t->u.kenum = e;
-
- return t;
-}
-
-/* Make a pointer to a given type. */
-
-debug_type
-debug_make_pointer_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- if (type->pointer != DEBUG_TYPE_NULL)
- return type->pointer;
-
- t = debug_make_type (info, DEBUG_KIND_POINTER, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kpointer = type;
-
- type->pointer = t;
-
- return t;
-}
-
-/* Make a function returning a given type. FIXME: We should be able
- to record the parameter types. */
-
-debug_type
-debug_make_function_type (handle, type, arg_types, varargs)
- PTR handle;
- debug_type type;
- debug_type *arg_types;
- boolean varargs;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_function_type *f;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- f = (struct debug_function_type *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->return_type = type;
- f->arg_types = arg_types;
- f->varargs = varargs;
-
- t->u.kfunction = f;
-
- return t;
-}
-
-/* Make a reference to a given type. */
-
-debug_type
-debug_make_reference_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kreference = type;
-
- return t;
-}
-
-/* Make a range of a given type from a lower to an upper bound. */
-
-debug_type
-debug_make_range_type (handle, type, lower, upper)
- PTR handle;
- debug_type type;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_range_type *r;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_RANGE, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- r = (struct debug_range_type *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
-
- r->type = type;
- r->lower = lower;
- r->upper = upper;
-
- t->u.krange = r;
-
- return t;
-}
-
-/* Make an array type. The second argument is the type of an element
- of the array. The third argument is the type of a range of the
- array. The fourth and fifth argument are the lower and upper
- bounds, respectively. The sixth argument is true if this array is
- actually a string, as in C. */
-
-debug_type
-debug_make_array_type (handle, element_type, range_type, lower, upper,
- stringp)
- PTR handle;
- debug_type element_type;
- debug_type range_type;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
- boolean stringp;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_array_type *a;
-
- if (element_type == NULL || range_type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_ARRAY, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- a = (struct debug_array_type *) xmalloc (sizeof *a);
- memset (a, 0, sizeof *a);
-
- a->element_type = element_type;
- a->range_type = range_type;
- a->lower = lower;
- a->upper = upper;
- a->stringp = stringp;
-
- t->u.karray = a;
-
- return t;
-}
-
-/* Make a set of a given type. For example, a Pascal set type. The
- boolean argument is true if this set is actually a bitstring, as in
- CHILL. */
-
-debug_type
-debug_make_set_type (handle, type, bitstringp)
- PTR handle;
- debug_type type;
- boolean bitstringp;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_set_type *s;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_SET, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- s = (struct debug_set_type *) xmalloc (sizeof *s);
- memset (s, 0, sizeof *s);
-
- s->type = type;
- s->bitstringp = bitstringp;
-
- t->u.kset = s;
-
- return t;
-}
-
-/* Make a type for a pointer which is relative to an object. The
- second argument is the type of the object to which the pointer is
- relative. The third argument is the type that the pointer points
- to. */
-
-debug_type
-debug_make_offset_type (handle, base_type, target_type)
- PTR handle;
- debug_type base_type;
- debug_type target_type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_offset_type *o;
-
- if (base_type == NULL || target_type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_OFFSET, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- o = (struct debug_offset_type *) xmalloc (sizeof *o);
- memset (o, 0, sizeof *o);
-
- o->base_type = base_type;
- o->target_type = target_type;
-
- t->u.koffset = o;
-
- return t;
-}
-
-/* Make a type for a method function. The second argument is the
- return type, the third argument is the domain, and the fourth
- argument is a NULL terminated array of argument types. */
-
-debug_type
-debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
- PTR handle;
- debug_type return_type;
- debug_type domain_type;
- debug_type *arg_types;
- boolean varargs;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_method_type *m;
-
- if (return_type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_METHOD, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- m = (struct debug_method_type *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->return_type = return_type;
- m->domain_type = domain_type;
- m->arg_types = arg_types;
- m->varargs = varargs;
-
- t->u.kmethod = m;
-
- return t;
-}
-
-/* Make a const qualified version of a given type. */
-
-debug_type
-debug_make_const_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_CONST, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kconst = type;
-
- return t;
-}
-
-/* Make a volatile qualified version of a given type. */
-
-debug_type
-debug_make_volatile_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kvolatile = type;
-
- return t;
-}
-
-/* Make an undefined tagged type. For example, a struct which has
- been mentioned, but not defined. */
-
-debug_type
-debug_make_undefined_tagged_type (handle, name, kind)
- PTR handle;
- const char *name;
- enum debug_type_kind kind;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (name == NULL)
- return DEBUG_TYPE_NULL;
-
- switch (kind)
- {
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- case DEBUG_KIND_ENUM:
- break;
-
- default:
- debug_error ("debug_make_undefined_type: unsupported kind");
- return DEBUG_TYPE_NULL;
- }
-
- t = debug_make_type (info, kind, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- return debug_tag_type (handle, name, t);
-}
-
-/* Make a base class for an object. The second argument is the base
- class type. The third argument is the bit position of this base
- class in the object (always 0 unless doing multiple inheritance).
- The fourth argument is whether this is a virtual class. The fifth
- argument is the visibility of the base class. */
-
-/*ARGSUSED*/
-debug_baseclass
-debug_make_baseclass (handle, type, bitpos, virtual, visibility)
- PTR handle;
- debug_type type;
- bfd_vma bitpos;
- boolean virtual;
- enum debug_visibility visibility;
-{
- struct debug_baseclass *b;
-
- b = (struct debug_baseclass *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
-
- b->type = type;
- b->bitpos = bitpos;
- b->virtual = virtual;
- b->visibility = visibility;
-
- return b;
-}
-
-/* Make a field for a struct. The second argument is the name. The
- third argument is the type of the field. The fourth argument is
- the bit position of the field. The fifth argument is the size of
- the field (it may be zero). The sixth argument is the visibility
- of the field. */
-
-/*ARGSUSED*/
-debug_field
-debug_make_field (handle, name, type, bitpos, bitsize, visibility)
- PTR handle;
- const char *name;
- debug_type type;
- bfd_vma bitpos;
- bfd_vma bitsize;
- enum debug_visibility visibility;
-{
- struct debug_field *f;
-
- f = (struct debug_field *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->name = name;
- f->type = type;
- f->static_member = false;
- f->u.f.bitpos = bitpos;
- f->u.f.bitsize = bitsize;
- f->visibility = visibility;
-
- return f;
-}
-
-/* Make a static member of an object. The second argument is the
- name. The third argument is the type of the member. The fourth
- argument is the physical name of the member (i.e., the name as a
- global variable). The fifth argument is the visibility of the
- member. */
-
-/*ARGSUSED*/
-debug_field
-debug_make_static_member (handle, name, type, physname, visibility)
- PTR handle;
- const char *name;
- debug_type type;
- const char *physname;
- enum debug_visibility visibility;
-{
- struct debug_field *f;
-
- f = (struct debug_field *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->name = name;
- f->type = type;
- f->static_member = true;
- f->u.s.physname = physname;
- f->visibility = visibility;
-
- return f;
-}
-
-/* Make a method. The second argument is the name, and the third
- argument is a NULL terminated array of method variants. */
-
-/*ARGSUSED*/
-debug_method
-debug_make_method (handle, name, variants)
- PTR handle;
- const char *name;
- debug_method_variant *variants;
-{
- struct debug_method *m;
-
- m = (struct debug_method *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->name = name;
- m->variants = variants;
-
- return m;
-}
-
-/* Make a method argument. The second argument is the real name of
- the function. The third argument is the type of the function. The
- fourth argument is the visibility. The fifth argument is whether
- this is a const function. The sixth argument is whether this is a
- volatile function. The seventh argument is the offset in the
- virtual function table, if any. The eighth argument is the virtual
- function context. FIXME: Are the const and volatile arguments
- necessary? Could we just use debug_make_const_type? */
-
-/*ARGSUSED*/
-debug_method_variant
-debug_make_method_variant (handle, physname, type, visibility, constp,
- volatilep, voffset, context)
- PTR handle;
- const char *physname;
- debug_type type;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- debug_type context;
-{
- struct debug_method_variant *m;
-
- m = (struct debug_method_variant *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->physname = physname;
- m->type = type;
- m->visibility = visibility;
- m->constp = constp;
- m->volatilep = volatilep;
- m->voffset = voffset;
- m->context = context;
-
- return m;
-}
-
-/* Make a static method argument. The arguments are the same as for
- debug_make_method_variant, except that the last two are omitted
- since a static method can not also be virtual. */
-
-debug_method_variant
-debug_make_static_method_variant (handle, physname, type, visibility,
- constp, volatilep)
- PTR handle;
- const char *physname;
- debug_type type;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
-{
- struct debug_method_variant *m;
-
- m = (struct debug_method_variant *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->physname = physname;
- m->type = type;
- m->visibility = visibility;
- m->constp = constp;
- m->volatilep = volatilep;
- m->voffset = VOFFSET_STATIC_METHOD;
-
- return m;
-}
-
-/* Name a type. */
-
-debug_type
-debug_name_type (handle, name, type)
- PTR handle;
- const char *name;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_named_type *n;
- struct debug_name *nm;
-
- if (name == NULL || type == NULL)
- return DEBUG_TYPE_NULL;
-
- if (info->current_unit == NULL
- || info->current_file == NULL)
- {
- debug_error ("debug_name_type: no current file");
- return DEBUG_TYPE_NULL;
- /* return false; */
- }
-
- t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- n = (struct debug_named_type *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->type = type;
-
- t->u.knamed = n;
-
- /* We always add the name to the global namespace. This is probably
- wrong in some cases, but it seems to be right for stabs. FIXME. */
-
- nm = debug_add_to_namespace (info, &info->current_file->globals, name,
- DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
- if (nm == NULL)
- return DEBUG_TYPE_NULL;
-
- nm->u.type = t;
-
- n->name = nm;
-
- return t;
-}
-
-/* Tag a type. */
-
-debug_type
-debug_tag_type (handle, name, type)
- PTR handle;
- const char *name;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_named_type *n;
- struct debug_name *nm;
-
- if (name == NULL || type == NULL)
- return DEBUG_TYPE_NULL;
-
- if (info->current_file == NULL)
- {
- debug_error ("debug_tag_type: no current file");
- return DEBUG_TYPE_NULL;
- }
-
- if (type->kind == DEBUG_KIND_TAGGED)
- {
- if (strcmp (type->u.knamed->name->name, name) == 0)
- return type;
- debug_error ("debug_tag_type: extra tag attempted");
- return DEBUG_TYPE_NULL;
- }
-
- t = debug_make_type (info, DEBUG_KIND_TAGGED, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- n = (struct debug_named_type *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->type = type;
-
- t->u.knamed = n;
-
- /* We keep a global namespace of tags for each compilation unit. I
- don't know if that is the right thing to do. */
-
- nm = debug_add_to_namespace (info, &info->current_file->globals, name,
- DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
- if (nm == NULL)
- return DEBUG_TYPE_NULL;
-
- nm->u.tag = t;
-
- n->name = nm;
-
- return t;
-}
-
-/* Record the size of a given type. */
-
-/*ARGSUSED*/
-boolean
-debug_record_type_size (handle, type, size)
- PTR handle;
- debug_type type;
- unsigned int size;
-{
-#if 0
- if (type->size != 0 && type->size != size)
- fprintf (stderr, "Warning: changing type size from %d to %d\n",
- type->size, size);
-#endif
-
- type->size = size;
-
- return true;
-}
-
-/* Find a named type. */
-
-debug_type
-debug_find_named_type (handle, name)
- PTR handle;
- const char *name;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_block *b;
- struct debug_file *f;
-
- /* We only search the current compilation unit. I don't know if
- this is right or not. */
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_find_named_type: no current compilation unit");
- return DEBUG_TYPE_NULL;
- }
-
- for (b = info->current_block; b != NULL; b = b->parent)
- {
- if (b->locals != NULL)
- {
- struct debug_name *n;
-
- for (n = b->locals->list; n != NULL; n = n->next)
- {
- if (n->kind == DEBUG_OBJECT_TYPE
- && n->name[0] == name[0]
- && strcmp (n->name, name) == 0)
- return n->u.type;
- }
- }
- }
-
- for (f = info->current_unit->files; f != NULL; f = f->next)
- {
- if (f->globals != NULL)
- {
- struct debug_name *n;
-
- for (n = f->globals->list; n != NULL; n = n->next)
- {
- if (n->kind == DEBUG_OBJECT_TYPE
- && n->name[0] == name[0]
- && strcmp (n->name, name) == 0)
- return n->u.type;
- }
- }
- }
-
- return DEBUG_TYPE_NULL;
-}
-
-/* Find a tagged type. */
-
-debug_type
-debug_find_tagged_type (handle, name, kind)
- PTR handle;
- const char *name;
- enum debug_type_kind kind;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_unit *u;
-
- /* We search the globals of all the compilation units. I don't know
- if this is correct or not. It would be easy to change. */
-
- for (u = info->units; u != NULL; u = u->next)
- {
- struct debug_file *f;
-
- for (f = u->files; f != NULL; f = f->next)
- {
- struct debug_name *n;
-
- if (f->globals != NULL)
- {
- for (n = f->globals->list; n != NULL; n = n->next)
- {
- if (n->kind == DEBUG_OBJECT_TAG
- && (kind == DEBUG_KIND_ILLEGAL
- || n->u.tag->kind == kind)
- && n->name[0] == name[0]
- && strcmp (n->name, name) == 0)
- return n->u.tag;
- }
- }
- }
- }
-
- return DEBUG_TYPE_NULL;
-}
-
-/* Get a base type. */
-
-static struct debug_type *
-debug_get_real_type (handle, type)
- PTR handle;
- debug_type type;
-{
- switch (type->kind)
- {
- default:
- return type;
- case DEBUG_KIND_INDIRECT:
- if (*type->u.kindirect->slot != NULL)
- return debug_get_real_type (handle, *type->u.kindirect->slot);
- return type;
- case DEBUG_KIND_NAMED:
- case DEBUG_KIND_TAGGED:
- return debug_get_real_type (handle, type->u.knamed->type);
- }
- /*NOTREACHED*/
-}
-
-/* Get the kind of a type. */
-
-enum debug_type_kind
-debug_get_type_kind (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return DEBUG_KIND_ILLEGAL;
- type = debug_get_real_type (handle, type);
- return type->kind;
-}
-
-/* Get the name of a type. */
-
-const char *
-debug_get_type_name (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type->kind == DEBUG_KIND_INDIRECT)
- {
- if (*type->u.kindirect->slot != NULL)
- return debug_get_type_name (handle, *type->u.kindirect->slot);
- return type->u.kindirect->tag;
- }
- if (type->kind == DEBUG_KIND_NAMED
- || type->kind == DEBUG_KIND_TAGGED)
- return type->u.knamed->name->name;
- return NULL;
-}
-
-/* Get the size of a type. */
-
-bfd_vma
-debug_get_type_size (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return 0;
-
- /* We don't call debug_get_real_type, because somebody might have
- called debug_record_type_size on a named or indirect type. */
-
- if (type->size != 0)
- return type->size;
-
- switch (type->kind)
- {
- default:
- return 0;
- case DEBUG_KIND_INDIRECT:
- if (*type->u.kindirect->slot != NULL)
- return debug_get_type_size (handle, *type->u.kindirect->slot);
- return 0;
- case DEBUG_KIND_NAMED:
- case DEBUG_KIND_TAGGED:
- return debug_get_type_size (handle, type->u.knamed->type);
- }
- /*NOTREACHED*/
-}
-
-/* Get the return type of a function or method type. */
-
-debug_type
-debug_get_return_type (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return DEBUG_TYPE_NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return DEBUG_TYPE_NULL;
- case DEBUG_KIND_FUNCTION:
- return type->u.kfunction->return_type;
- case DEBUG_KIND_METHOD:
- return type->u.kmethod->return_type;
- }
- /*NOTREACHED*/
-}
-
-/* Get the parameter types of a function or method type (except that
- we don't currently store the parameter types of a function). */
-
-const debug_type *
-debug_get_parameter_types (handle, type, pvarargs)
- PTR handle;
- debug_type type;
- boolean *pvarargs;
-{
- if (type == NULL)
- return NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return NULL;
- case DEBUG_KIND_FUNCTION:
- *pvarargs = type->u.kfunction->varargs;
- return type->u.kfunction->arg_types;
- case DEBUG_KIND_METHOD:
- *pvarargs = type->u.kmethod->varargs;
- return type->u.kmethod->arg_types;
- }
- /*NOTREACHED*/
-}
-
-/* Get the target type of a type. */
-
-debug_type
-debug_get_target_type (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return NULL;
- case DEBUG_KIND_POINTER:
- return type->u.kpointer;
- case DEBUG_KIND_REFERENCE:
- return type->u.kreference;
- case DEBUG_KIND_CONST:
- return type->u.kconst;
- case DEBUG_KIND_VOLATILE:
- return type->u.kvolatile;
- }
- /*NOTREACHED*/
-}
-
-/* Get the NULL terminated array of fields for a struct, union, or
- class. */
-
-const debug_field *
-debug_get_fields (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return NULL;
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- return type->u.kclass->fields;
- }
- /*NOTREACHED*/
-}
-
-/* Get the type of a field. */
-
-/*ARGSUSED*/
-debug_type
-debug_get_field_type (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL)
- return NULL;
- return field->type;
-}
-
-/* Get the name of a field. */
-
-/*ARGSUSED*/
-const char *
-debug_get_field_name (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL)
- return NULL;
- return field->name;
-}
-
-/* Get the bit position of a field. */
-
-/*ARGSUSED*/
-bfd_vma
-debug_get_field_bitpos (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL || field->static_member)
- return (bfd_vma) -1;
- return field->u.f.bitpos;
-}
-
-/* Get the bit size of a field. */
-
-/*ARGSUSED*/
-bfd_vma
-debug_get_field_bitsize (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL || field->static_member)
- return (bfd_vma) -1;
- return field->u.f.bitsize;
-}
-
-/* Get the visibility of a field. */
-
-/*ARGSUSED*/
-enum debug_visibility
-debug_get_field_visibility (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL)
- return DEBUG_VISIBILITY_IGNORE;
- return field->visibility;
-}
-
-/* Get the physical name of a field. */
-
-const char *
-debug_get_field_physname (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL || ! field->static_member)
- return NULL;
- return field->u.s.physname;
-}
-
-/* Write out the debugging information. This is given a handle to
- debugging information, and a set of function pointers to call. */
-
-boolean
-debug_write (handle, fns, fhandle)
- PTR handle;
- const struct debug_write_fns *fns;
- PTR fhandle;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_unit *u;
-
- /* We use a mark to tell whether we have already written out a
- particular name. We use an integer, so that we don't have to
- clear the mark fields if we happen to write out the same
- information more than once. */
- ++info->mark;
-
- /* The base_id field holds an ID value which will never be used, so
- that we can tell whether we have assigned an ID during this call
- to debug_write. */
- info->base_id = info->class_id;
-
- /* We keep a linked list of classes for which was have assigned ID's
- during this call to debug_write. */
- info->id_list = NULL;
-
- for (u = info->units; u != NULL; u = u->next)
- {
- struct debug_file *f;
- boolean first_file;
-
- info->current_write_lineno = u->linenos;
- info->current_write_lineno_index = 0;
-
- if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
- return false;
-
- first_file = true;
- for (f = u->files; f != NULL; f = f->next)
- {
- struct debug_name *n;
-
- if (first_file)
- first_file = false;
- else
- {
- if (! (*fns->start_source) (fhandle, f->filename))
- return false;
- }
-
- if (f->globals != NULL)
- {
- for (n = f->globals->list; n != NULL; n = n->next)
- {
- if (! debug_write_name (info, fns, fhandle, n))
- return false;
- }
- }
- }
-
- /* Output any line number information which hasn't already been
- handled. */
- if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
- return false;
- }
-
- return true;
-}
-
-/* Write out an element in a namespace. */
-
-static boolean
-debug_write_name (info, fns, fhandle, n)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_name *n;
-{
- switch (n->kind)
- {
- case DEBUG_OBJECT_TYPE:
- if (! debug_write_type (info, fns, fhandle, n->u.type, n)
- || ! (*fns->typdef) (fhandle, n->name))
- return false;
- return true;
- case DEBUG_OBJECT_TAG:
- if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
- return false;
- return (*fns->tag) (fhandle, n->name);
- case DEBUG_OBJECT_VARIABLE:
- if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
- n->u.variable->val);
- case DEBUG_OBJECT_FUNCTION:
- return debug_write_function (info, fns, fhandle, n->name,
- n->linkage, n->u.function);
- case DEBUG_OBJECT_INT_CONSTANT:
- return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);
- case DEBUG_OBJECT_FLOAT_CONSTANT:
- return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);
- case DEBUG_OBJECT_TYPED_CONSTANT:
- if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->typed_constant) (fhandle, n->name,
- n->u.typed_constant->val);
- default:
- abort ();
- return false;
- }
- /*NOTREACHED*/
-}
-
-/* Write out a type. If the type is DEBUG_KIND_NAMED or
- DEBUG_KIND_TAGGED, then the name argument is the name for which we
- are about to call typedef or tag. If the type is anything else,
- then the name argument is a tag from a DEBUG_KIND_TAGGED type which
- points to this one. */
-
-static boolean
-debug_write_type (info, fns, fhandle, type, name)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_type *type;
- struct debug_name *name;
-{
- unsigned int i;
- int is;
- const char *tag;
-
- /* If we have a name for this type, just output it. We only output
- typedef names after they have been defined. We output type tags
- whenever we are not actually defining them. */
- if ((type->kind == DEBUG_KIND_NAMED
- || type->kind == DEBUG_KIND_TAGGED)
- && (type->u.knamed->name->mark == info->mark
- || (type->kind == DEBUG_KIND_TAGGED
- && type->u.knamed->name != name)))
- {
- if (type->kind == DEBUG_KIND_NAMED)
- return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
- else
- {
- struct debug_type *real;
- unsigned int id;
-
- real = debug_get_real_type ((PTR) info, type);
- id = 0;
- if ((real->kind == DEBUG_KIND_STRUCT
- || real->kind == DEBUG_KIND_UNION
- || real->kind == DEBUG_KIND_CLASS
- || real->kind == DEBUG_KIND_UNION_CLASS)
- && real->u.kclass != NULL)
- {
- if (real->u.kclass->id <= info->base_id)
- {
- if (! debug_set_class_id (info,
- type->u.knamed->name->name,
- real))
- return false;
- }
- id = real->u.kclass->id;
- }
-
- return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,
- real->kind);
- }
- }
-
- /* Mark the name after we have already looked for a known name, so
- that we don't just define a type in terms of itself. We need to
- mark the name here so that a struct containing a pointer to
- itself will work. */
- if (name != NULL)
- name->mark = info->mark;
-
- tag = NULL;
- if (name != NULL
- && type->kind != DEBUG_KIND_NAMED
- && type->kind != DEBUG_KIND_TAGGED)
- {
- assert (name->kind == DEBUG_OBJECT_TAG);
- tag = name->name;
- }
-
- switch (type->kind)
- {
- case DEBUG_KIND_ILLEGAL:
- debug_error ("debug_write_type: illegal type encountered");
- return false;
- case DEBUG_KIND_INDIRECT:
- if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
- return (*fns->empty_type) (fhandle);
- return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot,
- name);
- case DEBUG_KIND_VOID:
- return (*fns->void_type) (fhandle);
- case DEBUG_KIND_INT:
- return (*fns->int_type) (fhandle, type->size, type->u.kint);
- case DEBUG_KIND_FLOAT:
- return (*fns->float_type) (fhandle, type->size);
- case DEBUG_KIND_COMPLEX:
- return (*fns->complex_type) (fhandle, type->size);
- case DEBUG_KIND_BOOL:
- return (*fns->bool_type) (fhandle, type->size);
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- if (type->u.kclass != NULL)
- {
- if (type->u.kclass->id <= info->base_id)
- {
- if (! debug_set_class_id (info, tag, type))
- return false;
- }
-
- if (info->mark == type->u.kclass->mark)
- {
- /* We are currently outputting this struct, or we have
- already output it. I don't know if this can happen,
- but it can happen for a class. */
- assert (type->u.kclass->id > info->base_id);
- return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
- type->kind);
- }
- type->u.kclass->mark = info->mark;
- }
-
- if (! (*fns->start_struct_type) (fhandle, tag,
- (type->u.kclass != NULL
- ? type->u.kclass->id
- : 0),
- type->kind == DEBUG_KIND_STRUCT,
- type->size))
- return false;
- if (type->u.kclass != NULL
- && type->u.kclass->fields != NULL)
- {
- for (i = 0; type->u.kclass->fields[i] != NULL; i++)
- {
- struct debug_field *f;
-
- f = type->u.kclass->fields[i];
- if (! debug_write_type (info, fns, fhandle, f->type,
- (struct debug_name *) NULL)
- || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
- f->u.f.bitsize, f->visibility))
- return false;
- }
- }
- return (*fns->end_struct_type) (fhandle);
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- return debug_write_class_type (info, fns, fhandle, type, tag);
- case DEBUG_KIND_ENUM:
- if (type->u.kenum == NULL)
- return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
- (bfd_signed_vma *) NULL);
- return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
- type->u.kenum->values);
- case DEBUG_KIND_POINTER:
- if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
- (struct debug_name *) NULL))
- return false;
- return (*fns->pointer_type) (fhandle);
- case DEBUG_KIND_FUNCTION:
- if (! debug_write_type (info, fns, fhandle,
- type->u.kfunction->return_type,
- (struct debug_name *) NULL))
- return false;
- if (type->u.kfunction->arg_types == NULL)
- is = -1;
- else
- {
- for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
- if (! debug_write_type (info, fns, fhandle,
- type->u.kfunction->arg_types[is],
- (struct debug_name *) NULL))
- return false;
- }
- return (*fns->function_type) (fhandle, is,
- type->u.kfunction->varargs);
- case DEBUG_KIND_REFERENCE:
- if (! debug_write_type (info, fns, fhandle, type->u.kreference,
- (struct debug_name *) NULL))
- return false;
- return (*fns->reference_type) (fhandle);
- case DEBUG_KIND_RANGE:
- if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->range_type) (fhandle, type->u.krange->lower,
- type->u.krange->upper);
- case DEBUG_KIND_ARRAY:
- if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type,
- (struct debug_name *) NULL)
- || ! debug_write_type (info, fns, fhandle,
- type->u.karray->range_type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->array_type) (fhandle, type->u.karray->lower,
- type->u.karray->upper,
- type->u.karray->stringp);
- case DEBUG_KIND_SET:
- if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
- case DEBUG_KIND_OFFSET:
- if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
- (struct debug_name *) NULL)
- || ! debug_write_type (info, fns, fhandle,
- type->u.koffset->target_type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->offset_type) (fhandle);
- case DEBUG_KIND_METHOD:
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->return_type,
- (struct debug_name *) NULL))
- return false;
- if (type->u.kmethod->arg_types == NULL)
- is = -1;
- else
- {
- for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->arg_types[is],
- (struct debug_name *) NULL))
- return false;
- }
- if (type->u.kmethod->domain_type != NULL)
- {
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->domain_type,
- (struct debug_name *) NULL))
- return false;
- }
- return (*fns->method_type) (fhandle,
- type->u.kmethod->domain_type != NULL,
- is,
- type->u.kmethod->varargs);
- case DEBUG_KIND_CONST:
- if (! debug_write_type (info, fns, fhandle, type->u.kconst,
- (struct debug_name *) NULL))
- return false;
- return (*fns->const_type) (fhandle);
- case DEBUG_KIND_VOLATILE:
- if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
- (struct debug_name *) NULL))
- return false;
- return (*fns->volatile_type) (fhandle);
- case DEBUG_KIND_NAMED:
- return debug_write_type (info, fns, fhandle, type->u.knamed->type,
- (struct debug_name *) NULL);
- case DEBUG_KIND_TAGGED:
- return debug_write_type (info, fns, fhandle, type->u.knamed->type,
- type->u.knamed->name);
- default:
- abort ();
- return false;
- }
-}
-
-/* Write out a class type. */
-
-static boolean
-debug_write_class_type (info, fns, fhandle, type, tag)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_type *type;
- const char *tag;
-{
- unsigned int i;
- unsigned int id;
- struct debug_type *vptrbase;
-
- if (type->u.kclass == NULL)
- {
- id = 0;
- vptrbase = NULL;
- }
- else
- {
- if (type->u.kclass->id <= info->base_id)
- {
- if (! debug_set_class_id (info, tag, type))
- return false;
- }
-
- if (info->mark == type->u.kclass->mark)
- {
- /* We are currently outputting this class, or we have
- already output it. This can happen when there are
- methods for an anonymous class. */
- assert (type->u.kclass->id > info->base_id);
- return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
- type->kind);
- }
- type->u.kclass->mark = info->mark;
- id = type->u.kclass->id;
-
- vptrbase = type->u.kclass->vptrbase;
- if (vptrbase != NULL && vptrbase != type)
- {
- if (! debug_write_type (info, fns, fhandle, vptrbase,
- (struct debug_name *) NULL))
- return false;
- }
- }
-
- if (! (*fns->start_class_type) (fhandle, tag, id,
- type->kind == DEBUG_KIND_CLASS,
- type->size,
- vptrbase != NULL,
- vptrbase == type))
- return false;
-
- if (type->u.kclass != NULL)
- {
- if (type->u.kclass->fields != NULL)
- {
- for (i = 0; type->u.kclass->fields[i] != NULL; i++)
- {
- struct debug_field *f;
-
- f = type->u.kclass->fields[i];
- if (! debug_write_type (info, fns, fhandle, f->type,
- (struct debug_name *) NULL))
- return false;
- if (f->static_member)
- {
- if (! (*fns->class_static_member) (fhandle, f->name,
- f->u.s.physname,
- f->visibility))
- return false;
- }
- else
- {
- if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
- f->u.f.bitsize, f->visibility))
- return false;
- }
- }
- }
-
- if (type->u.kclass->baseclasses != NULL)
- {
- for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
- {
- struct debug_baseclass *b;
-
- b = type->u.kclass->baseclasses[i];
- if (! debug_write_type (info, fns, fhandle, b->type,
- (struct debug_name *) NULL))
- return false;
- if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
- b->visibility))
- return false;
- }
- }
-
- if (type->u.kclass->methods != NULL)
- {
- for (i = 0; type->u.kclass->methods[i] != NULL; i++)
- {
- struct debug_method *m;
- unsigned int j;
-
- m = type->u.kclass->methods[i];
- if (! (*fns->class_start_method) (fhandle, m->name))
- return false;
- for (j = 0; m->variants[j] != NULL; j++)
- {
- struct debug_method_variant *v;
-
- v = m->variants[j];
- if (v->context != NULL)
- {
- if (! debug_write_type (info, fns, fhandle, v->context,
- (struct debug_name *) NULL))
- return false;
- }
- if (! debug_write_type (info, fns, fhandle, v->type,
- (struct debug_name *) NULL))
- return false;
- if (v->voffset != VOFFSET_STATIC_METHOD)
- {
- if (! (*fns->class_method_variant) (fhandle, v->physname,
- v->visibility,
- v->constp,
- v->volatilep,
- v->voffset,
- v->context != NULL))
- return false;
- }
- else
- {
- if (! (*fns->class_static_method_variant) (fhandle,
- v->physname,
- v->visibility,
- v->constp,
- v->volatilep))
- return false;
- }
- }
- if (! (*fns->class_end_method) (fhandle))
- return false;
- }
- }
- }
-
- return (*fns->end_class_type) (fhandle);
-}
-
-/* Write out information for a function. */
-
-static boolean
-debug_write_function (info, fns, fhandle, name, linkage, function)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- const char *name;
- enum debug_object_linkage linkage;
- struct debug_function *function;
-{
- struct debug_parameter *p;
- struct debug_block *b;
-
- if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
- return false;
-
- if (! debug_write_type (info, fns, fhandle, function->return_type,
- (struct debug_name *) NULL))
- return false;
-
- if (! (*fns->start_function) (fhandle, name,
- linkage == DEBUG_LINKAGE_GLOBAL))
- return false;
-
- for (p = function->parameters; p != NULL; p = p->next)
- {
- if (! debug_write_type (info, fns, fhandle, p->type,
- (struct debug_name *) NULL)
- || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
- return false;
- }
-
- for (b = function->blocks; b != NULL; b = b->next)
- {
- if (! debug_write_block (info, fns, fhandle, b))
- return false;
- }
-
- return (*fns->end_function) (fhandle);
-}
-
-/* Write out information for a block. */
-
-static boolean
-debug_write_block (info, fns, fhandle, block)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_block *block;
-{
- struct debug_name *n;
- struct debug_block *b;
-
- if (! debug_write_linenos (info, fns, fhandle, block->start))
- return false;
-
- /* I can't see any point to writing out a block with no local
- variables, so we don't bother, except for the top level block. */
- if (block->locals != NULL || block->parent == NULL)
- {
- if (! (*fns->start_block) (fhandle, block->start))
- return false;
- }
-
- if (block->locals != NULL)
- {
- for (n = block->locals->list; n != NULL; n = n->next)
- {
- if (! debug_write_name (info, fns, fhandle, n))
- return false;
- }
- }
-
- for (b = block->children; b != NULL; b = b->next)
- {
- if (! debug_write_block (info, fns, fhandle, b))
- return false;
- }
-
- if (! debug_write_linenos (info, fns, fhandle, block->end))
- return false;
-
- if (block->locals != NULL || block->parent == NULL)
- {
- if (! (*fns->end_block) (fhandle, block->end))
- return false;
- }
-
- return true;
-}
-
-/* Write out line number information up to ADDRESS. */
-
-static boolean
-debug_write_linenos (info, fns, fhandle, address)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- bfd_vma address;
-{
- while (info->current_write_lineno != NULL)
- {
- struct debug_lineno *l;
-
- l = info->current_write_lineno;
-
- while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
- {
- if (l->linenos[info->current_write_lineno_index]
- == (unsigned long) -1)
- break;
-
- if (l->addrs[info->current_write_lineno_index] >= address)
- return true;
-
- if (! (*fns->lineno) (fhandle, l->file->filename,
- l->linenos[info->current_write_lineno_index],
- l->addrs[info->current_write_lineno_index]))
- return false;
-
- ++info->current_write_lineno_index;
- }
-
- info->current_write_lineno = l->next;
- info->current_write_lineno_index = 0;
- }
-
- return true;
-}
-
-/* Get the ID number for a class. If during the same call to
- debug_write we find a struct with the same definition with the same
- name, we use the same ID. This type of things happens because the
- same struct will be defined by multiple compilation units. */
-
-static boolean
-debug_set_class_id (info, tag, type)
- struct debug_handle *info;
- const char *tag;
- struct debug_type *type;
-{
- struct debug_class_type *c;
- struct debug_class_id *l;
-
- assert (type->kind == DEBUG_KIND_STRUCT
- || type->kind == DEBUG_KIND_UNION
- || type->kind == DEBUG_KIND_CLASS
- || type->kind == DEBUG_KIND_UNION_CLASS);
-
- c = type->u.kclass;
-
- if (c->id > info->base_id)
- return true;
-
- for (l = info->id_list; l != NULL; l = l->next)
- {
- if (l->type->kind != type->kind)
- continue;
-
- if (tag == NULL)
- {
- if (l->tag != NULL)
- continue;
- }
- else
- {
- if (l->tag == NULL
- || l->tag[0] != tag[0]
- || strcmp (l->tag, tag) != 0)
- continue;
- }
-
- if (debug_type_samep (info, l->type, type))
- {
- c->id = l->type->u.kclass->id;
- return true;
- }
- }
-
- /* There are no identical types. Use a new ID, and add it to the
- list. */
- ++info->class_id;
- c->id = info->class_id;
-
- l = (struct debug_class_id *) xmalloc (sizeof *l);
- memset (l, 0, sizeof *l);
-
- l->type = type;
- l->tag = tag;
-
- l->next = info->id_list;
- info->id_list = l;
-
- return true;
-}
-
-/* See if two types are the same. At this point, we don't care about
- tags and the like. */
-
-static boolean
-debug_type_samep (info, t1, t2)
- struct debug_handle *info;
- struct debug_type *t1;
- struct debug_type *t2;
-{
- struct debug_type_compare_list *l;
- struct debug_type_compare_list top;
- boolean ret;
-
- if (t1 == NULL)
- return t2 == NULL;
- if (t2 == NULL)
- return false;
-
- while (t1->kind == DEBUG_KIND_INDIRECT)
- {
- t1 = *t1->u.kindirect->slot;
- if (t1 == NULL)
- return false;
- }
- while (t2->kind == DEBUG_KIND_INDIRECT)
- {
- t2 = *t2->u.kindirect->slot;
- if (t2 == NULL)
- return false;
- }
-
- if (t1 == t2)
- return true;
-
- /* As a special case, permit a typedef to match a tag, since C++
- debugging output will sometimes add a typedef where C debugging
- output will not. */
- if (t1->kind == DEBUG_KIND_NAMED
- && t2->kind == DEBUG_KIND_TAGGED)
- return debug_type_samep (info, t1->u.knamed->type, t2);
- else if (t1->kind == DEBUG_KIND_TAGGED
- && t2->kind == DEBUG_KIND_NAMED)
- return debug_type_samep (info, t1, t2->u.knamed->type);
-
- if (t1->kind != t2->kind
- || t1->size != t2->size)
- return false;
-
- /* Get rid of the trivial cases first. */
- switch (t1->kind)
- {
- default:
- break;
- case DEBUG_KIND_VOID:
- case DEBUG_KIND_FLOAT:
- case DEBUG_KIND_COMPLEX:
- case DEBUG_KIND_BOOL:
- return true;
- case DEBUG_KIND_INT:
- return t1->u.kint == t2->u.kint;
- }
-
- /* We have to avoid an infinite recursion. We do this by keeping a
- list of types which we are comparing. We just keep the list on
- the stack. If we encounter a pair of types we are currently
- comparing, we just assume that they are equal. */
- for (l = info->compare_list; l != NULL; l = l->next)
- {
- if (l->t1 == t1 && l->t2 == t2)
- return true;
- }
-
- top.t1 = t1;
- top.t2 = t2;
- top.next = info->compare_list;
- info->compare_list = &top;
-
- switch (t1->kind)
- {
- default:
- abort ();
- ret = false;
- break;
-
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- if (t1->u.kclass == NULL)
- ret = t2->u.kclass == NULL;
- else if (t2->u.kclass == NULL)
- ret = false;
- else if (t1->u.kclass->id > info->base_id
- && t1->u.kclass->id == t2->u.kclass->id)
- ret = true;
- else
- ret = debug_class_type_samep (info, t1, t2);
- break;
-
- case DEBUG_KIND_ENUM:
- if (t1->u.kenum == NULL)
- ret = t2->u.kenum == NULL;
- else if (t2->u.kenum == NULL)
- ret = false;
- else
- {
- const char **pn1, **pn2;
- bfd_signed_vma *pv1, *pv2;
-
- pn1 = t1->u.kenum->names;
- pn2 = t2->u.kenum->names;
- pv1 = t1->u.kenum->values;
- pv2 = t2->u.kenum->values;
- while (*pn1 != NULL && *pn2 != NULL)
- {
- if (**pn1 != **pn2
- || *pv1 != *pv2
- || strcmp (*pn1, *pn2) != 0)
- break;
- ++pn1;
- ++pn2;
- ++pv1;
- ++pv2;
- }
- ret = *pn1 == NULL && *pn2 == NULL;
- }
- break;
-
- case DEBUG_KIND_POINTER:
- ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
- break;
-
- case DEBUG_KIND_FUNCTION:
- if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
- || ! debug_type_samep (info, t1->u.kfunction->return_type,
- t2->u.kfunction->return_type)
- || ((t1->u.kfunction->arg_types == NULL)
- != (t2->u.kfunction->arg_types == NULL)))
- ret = false;
- else if (t1->u.kfunction->arg_types == NULL)
- ret = true;
- else
- {
- struct debug_type **a1, **a2;
-
- a1 = t1->u.kfunction->arg_types;
- a2 = t2->u.kfunction->arg_types;
- while (*a1 != NULL && *a2 != NULL)
- if (! debug_type_samep (info, *a1, *a2))
- break;
- ret = *a1 == NULL && *a2 == NULL;
- }
- break;
-
- case DEBUG_KIND_REFERENCE:
- ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference);
- break;
-
- case DEBUG_KIND_RANGE:
- ret = (t1->u.krange->lower == t2->u.krange->lower
- && t1->u.krange->upper == t2->u.krange->upper
- && debug_type_samep (info, t1->u.krange->type,
- t2->u.krange->type));
-
- case DEBUG_KIND_ARRAY:
- ret = (t1->u.karray->lower == t2->u.karray->lower
- && t1->u.karray->upper == t2->u.karray->upper
- && t1->u.karray->stringp == t2->u.karray->stringp
- && debug_type_samep (info, t1->u.karray->element_type,
- t2->u.karray->element_type));
- break;
-
- case DEBUG_KIND_SET:
- ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp
- && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type));
- break;
-
- case DEBUG_KIND_OFFSET:
- ret = (debug_type_samep (info, t1->u.koffset->base_type,
- t2->u.koffset->base_type)
- && debug_type_samep (info, t1->u.koffset->target_type,
- t2->u.koffset->target_type));
- break;
-
- case DEBUG_KIND_METHOD:
- if (t1->u.kmethod->varargs != t2->u.kmethod->varargs
- || ! debug_type_samep (info, t1->u.kmethod->return_type,
- t2->u.kmethod->return_type)
- || ! debug_type_samep (info, t1->u.kmethod->domain_type,
- t2->u.kmethod->domain_type)
- || ((t1->u.kmethod->arg_types == NULL)
- != (t2->u.kmethod->arg_types == NULL)))
- ret = false;
- else if (t1->u.kmethod->arg_types == NULL)
- ret = true;
- else
- {
- struct debug_type **a1, **a2;
-
- a1 = t1->u.kmethod->arg_types;
- a2 = t2->u.kmethod->arg_types;
- while (*a1 != NULL && *a2 != NULL)
- if (! debug_type_samep (info, *a1, *a2))
- break;
- ret = *a1 == NULL && *a2 == NULL;
- }
- break;
-
- case DEBUG_KIND_CONST:
- ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst);
- break;
-
- case DEBUG_KIND_VOLATILE:
- ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile);
- break;
-
- case DEBUG_KIND_NAMED:
- case DEBUG_KIND_TAGGED:
- ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0
- && debug_type_samep (info, t1->u.knamed->type,
- t2->u.knamed->type));
- break;
- }
-
- info->compare_list = top.next;
-
- return ret;
-}
-
-/* See if two classes are the same. This is a subroutine of
- debug_type_samep. */
-
-static boolean
-debug_class_type_samep (info, t1, t2)
- struct debug_handle *info;
- struct debug_type *t1;
- struct debug_type *t2;
-{
- struct debug_class_type *c1, *c2;
-
- c1 = t1->u.kclass;
- c2 = t2->u.kclass;
-
- if ((c1->fields == NULL) != (c2->fields == NULL)
- || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
- || (c1->methods == NULL) != (c2->methods == NULL)
- || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
- return false;
-
- if (c1->fields != NULL)
- {
- struct debug_field **pf1, **pf2;
-
- for (pf1 = c1->fields, pf2 = c2->fields;
- *pf1 != NULL && *pf2 != NULL;
- pf1++, pf2++)
- {
- struct debug_field *f1, *f2;
-
- f1 = *pf1;
- f2 = *pf2;
- if (f1->name[0] != f2->name[0]
- || f1->visibility != f2->visibility
- || f1->static_member != f2->static_member)
- return false;
- if (f1->static_member)
- {
- if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
- return false;
- }
- else
- {
- if (f1->u.f.bitpos != f2->u.f.bitpos
- || f1->u.f.bitsize != f2->u.f.bitsize)
- return false;
- }
- /* We do the checks which require function calls last. We
- don't require that the types of fields have the same
- names, since that sometimes fails in the presence of
- typedefs and we really don't care. */
- if (strcmp (f1->name, f2->name) != 0
- || ! debug_type_samep (info,
- debug_get_real_type ((PTR) info,
- f1->type),
- debug_get_real_type ((PTR) info,
- f2->type)))
- return false;
- }
- if (*pf1 != NULL || *pf2 != NULL)
- return false;
- }
-
- if (c1->vptrbase != NULL)
- {
- if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
- return false;
- }
-
- if (c1->baseclasses != NULL)
- {
- struct debug_baseclass **pb1, **pb2;
-
- for (pb1 = c1->baseclasses, pb2 = c2->baseclasses;
- *pb1 != NULL && *pb2 != NULL;
- ++pb1, ++pb2)
- {
- struct debug_baseclass *b1, *b2;
-
- b1 = *pb1;
- b2 = *pb2;
- if (b1->bitpos != b2->bitpos
- || b1->virtual != b2->virtual
- || b1->visibility != b2->visibility
- || ! debug_type_samep (info, b1->type, b2->type))
- return false;
- }
- if (*pb1 != NULL || *pb2 != NULL)
- return false;
- }
-
- if (c1->methods != NULL)
- {
- struct debug_method **pm1, **pm2;
-
- for (pm1 = c1->methods, pm2 = c2->methods;
- *pm1 != NULL && *pm2 != NULL;
- ++pm1, ++pm2)
- {
- struct debug_method *m1, *m2;
-
- m1 = *pm1;
- m2 = *pm2;
- if (m1->name[0] != m2->name[0]
- || strcmp (m1->name, m2->name) != 0
- || (m1->variants == NULL) != (m2->variants == NULL))
- return false;
- if (m1->variants == NULL)
- {
- struct debug_method_variant **pv1, **pv2;
-
- for (pv1 = m1->variants, pv2 = m2->variants;
- *pv1 != NULL && *pv2 != NULL;
- ++pv1, ++pv2)
- {
- struct debug_method_variant *v1, *v2;
-
- v1 = *pv1;
- v2 = *pv2;
- if (v1->physname[0] != v2->physname[0]
- || v1->visibility != v2->visibility
- || v1->constp != v2->constp
- || v1->volatilep != v2->volatilep
- || v1->voffset != v2->voffset
- || (v1->context == NULL) != (v2->context == NULL)
- || strcmp (v1->physname, v2->physname) != 0
- || ! debug_type_samep (info, v1->type, v2->type))
- return false;
- if (v1->context != NULL)
- {
- if (! debug_type_samep (info, v1->context,
- v2->context))
- return false;
- }
- }
- if (*pv1 != NULL || *pv2 != NULL)
- return false;
- }
- }
- if (*pm1 != NULL || *pm2 != NULL)
- return false;
- }
-
- return true;
-}
diff --git a/pstack/debug.h b/pstack/debug.h
deleted file mode 100644
index a4d3d8306cd..00000000000
--- a/pstack/debug.h
+++ /dev/null
@@ -1,798 +0,0 @@
-/* debug.h -- Describe generic debugging information.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-/* This header file describes a generic debugging information format.
- We may eventually have readers which convert different formats into
- this generic format, and writers which write it out. The initial
- impetus for this was writing a convertor from stabs to HP IEEE-695
- debugging format. */
-
-/* Different kinds of types. */
-
-enum debug_type_kind
-{
- /* Not used. */
- DEBUG_KIND_ILLEGAL,
- /* Indirect via a pointer. */
- DEBUG_KIND_INDIRECT,
- /* Void. */
- DEBUG_KIND_VOID,
- /* Integer. */
- DEBUG_KIND_INT,
- /* Floating point. */
- DEBUG_KIND_FLOAT,
- /* Complex. */
- DEBUG_KIND_COMPLEX,
- /* Boolean. */
- DEBUG_KIND_BOOL,
- /* Struct. */
- DEBUG_KIND_STRUCT,
- /* Union. */
- DEBUG_KIND_UNION,
- /* Class. */
- DEBUG_KIND_CLASS,
- /* Union class (can this really happen?). */
- DEBUG_KIND_UNION_CLASS,
- /* Enumeration type. */
- DEBUG_KIND_ENUM,
- /* Pointer. */
- DEBUG_KIND_POINTER,
- /* Function. */
- DEBUG_KIND_FUNCTION,
- /* Reference. */
- DEBUG_KIND_REFERENCE,
- /* Range. */
- DEBUG_KIND_RANGE,
- /* Array. */
- DEBUG_KIND_ARRAY,
- /* Set. */
- DEBUG_KIND_SET,
- /* Based pointer. */
- DEBUG_KIND_OFFSET,
- /* Method. */
- DEBUG_KIND_METHOD,
- /* Const qualified type. */
- DEBUG_KIND_CONST,
- /* Volatile qualified type. */
- DEBUG_KIND_VOLATILE,
- /* Named type. */
- DEBUG_KIND_NAMED,
- /* Tagged type. */
- DEBUG_KIND_TAGGED
-};
-
-/* Different kinds of variables. */
-
-enum debug_var_kind
-{
- /* Not used. */
- DEBUG_VAR_ILLEGAL,
- /* A global variable. */
- DEBUG_GLOBAL,
- /* A static variable. */
- DEBUG_STATIC,
- /* A local static variable. */
- DEBUG_LOCAL_STATIC,
- /* A local variable. */
- DEBUG_LOCAL,
- /* A register variable. */
- DEBUG_REGISTER
-};
-
-/* Different kinds of function parameters. */
-
-enum debug_parm_kind
-{
- /* Not used. */
- DEBUG_PARM_ILLEGAL,
- /* A stack based parameter. */
- DEBUG_PARM_STACK,
- /* A register parameter. */
- DEBUG_PARM_REG,
- /* A stack based reference parameter. */
- DEBUG_PARM_REFERENCE,
- /* A register reference parameter. */
- DEBUG_PARM_REF_REG
-};
-
-/* Different kinds of visibility. */
-
-enum debug_visibility
-{
- /* A public field (e.g., a field in a C struct). */
- DEBUG_VISIBILITY_PUBLIC,
- /* A protected field. */
- DEBUG_VISIBILITY_PROTECTED,
- /* A private field. */
- DEBUG_VISIBILITY_PRIVATE,
- /* A field which should be ignored. */
- DEBUG_VISIBILITY_IGNORE
-};
-
-/* A type. */
-
-typedef struct debug_type *debug_type;
-
-#define DEBUG_TYPE_NULL ((debug_type) NULL)
-
-/* A field in a struct or union. */
-
-typedef struct debug_field *debug_field;
-
-#define DEBUG_FIELD_NULL ((debug_field) NULL)
-
-/* A base class for an object. */
-
-typedef struct debug_baseclass *debug_baseclass;
-
-#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL)
-
-/* A method of an object. */
-
-typedef struct debug_method *debug_method;
-
-#define DEBUG_METHOD_NULL ((debug_method) NULL)
-
-/* The arguments to a method function of an object. These indicate
- which method to run. */
-
-typedef struct debug_method_variant *debug_method_variant;
-
-#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL)
-
-/* This structure is passed to debug_write. It holds function
- pointers that debug_write will call based on the accumulated
- debugging information. */
-
-struct debug_write_fns
-{
- /* This is called at the start of each new compilation unit with the
- name of the main file in the new unit. */
- boolean (*start_compilation_unit) PARAMS ((PTR, const char *));
-
- /* This is called at the start of each source file within a
- compilation unit, before outputting any global information for
- that file. The argument is the name of the file. */
- boolean (*start_source) PARAMS ((PTR, const char *));
-
- /* Each writer must keep a stack of types. */
-
- /* Push an empty type onto the type stack. This type can appear if
- there is a reference to a type which is never defined. */
- boolean (*empty_type) PARAMS ((PTR));
-
- /* Push a void type onto the type stack. */
- boolean (*void_type) PARAMS ((PTR));
-
- /* Push an integer type onto the type stack, given the size and
- whether it is unsigned. */
- boolean (*int_type) PARAMS ((PTR, unsigned int, boolean));
-
- /* Push a floating type onto the type stack, given the size. */
- boolean (*float_type) PARAMS ((PTR, unsigned int));
-
- /* Push a complex type onto the type stack, given the size. */
- boolean (*complex_type) PARAMS ((PTR, unsigned int));
-
- /* Push a boolean type onto the type stack, given the size. */
- boolean (*bool_type) PARAMS ((PTR, unsigned int));
-
- /* Push an enum type onto the type stack, given the tag, a NULL
- terminated array of names and the associated values. If there is
- no tag, the tag argument will be NULL. If this is an undefined
- enum, the names and values arguments will be NULL. */
- boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
- bfd_signed_vma *));
-
- /* Pop the top type on the type stack, and push a pointer to that
- type onto the type stack. */
- boolean (*pointer_type) PARAMS ((PTR));
-
- /* Push a function type onto the type stack. The second argument
- indicates the number of argument types that have been pushed onto
- the stack. If the number of argument types is passed as -1, then
- the argument types of the function are unknown, and no types have
- been pushed onto the stack. The third argument is true if the
- function takes a variable number of arguments. The return type
- of the function is pushed onto the type stack below the argument
- types, if any. */
- boolean (*function_type) PARAMS ((PTR, int, boolean));
-
- /* Pop the top type on the type stack, and push a reference to that
- type onto the type stack. */
- boolean (*reference_type) PARAMS ((PTR));
-
- /* Pop the top type on the type stack, and push a range of that type
- with the given lower and upper bounds onto the type stack. */
- boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
-
- /* Push an array type onto the type stack. The top type on the type
- stack is the range, and the next type on the type stack is the
- element type. These should be popped before the array type is
- pushed. The arguments are the lower bound, the upper bound, and
- whether the array is a string. */
- boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma,
- boolean));
-
- /* Pop the top type on the type stack, and push a set of that type
- onto the type stack. The argument indicates whether this set is
- a bitstring. */
- boolean (*set_type) PARAMS ((PTR, boolean));
-
- /* Push an offset type onto the type stack. The top type on the
- type stack is the target type, and the next type on the type
- stack is the base type. These should be popped before the offset
- type is pushed. */
- boolean (*offset_type) PARAMS ((PTR));
-
- /* Push a method type onto the type stack. If the second argument
- is true, the top type on the stack is the class to which the
- method belongs; otherwise, the class must be determined by the
- class to which the method is attached. The third argument is the
- number of argument types; these are pushed onto the type stack in
- reverse order (the first type popped is the last argument to the
- method). A value of -1 for the third argument means that no
- argument information is available. The fourth argument is true
- if the function takes a variable number of arguments. The next
- type on the type stack below the domain and the argument types is
- the return type of the method. All these types must be popped,
- and then the method type must be pushed. */
- boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
-
- /* Pop the top type off the type stack, and push a const qualified
- version of that type onto the type stack. */
- boolean (*const_type) PARAMS ((PTR));
-
- /* Pop the top type off the type stack, and push a volatile
- qualified version of that type onto the type stack. */
- boolean (*volatile_type) PARAMS ((PTR));
-
- /* Start building a struct. This is followed by calls to the
- struct_field function, and finished by a call to the
- end_struct_type function. The second argument is the tag; this
- will be NULL if there isn't one. If the second argument is NULL,
- the third argument is a constant identifying this struct for use
- with tag_type. The fourth argument is true for a struct, false
- for a union. The fifth argument is the size. If this is an
- undefined struct or union, the size will be 0 and struct_field
- will not be called before end_struct_type is called. */
- boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int,
- boolean, unsigned int));
-
- /* Add a field to the struct type currently being built. The type
- of the field should be popped off the type stack. The arguments
- are the name, the bit position, the bit size (may be zero if the
- field is not packed), and the visibility. */
- boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma,
- enum debug_visibility));
-
- /* Finish building a struct, and push it onto the type stack. */
- boolean (*end_struct_type) PARAMS ((PTR));
-
- /* Start building a class. This is followed by calls to several
- functions: struct_field, class_static_member, class_baseclass,
- class_start_method, class_method_variant,
- class_static_method_variant, and class_end_method. The class is
- finished by a call to end_class_type. The first five arguments
- are the same as for start_struct_type. The sixth argument is
- true if there is a virtual function table; if there is, the
- seventh argument is true if the virtual function table can be
- found in the type itself, and is false if the type of the object
- holding the virtual function table should be popped from the type
- stack. */
- boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int,
- boolean, unsigned int, boolean,
- boolean));
-
- /* Add a static member to the class currently being built. The
- arguments are the field name, the physical name, and the
- visibility. The type must be popped off the type stack. */
- boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
- enum debug_visibility));
-
- /* Add a baseclass to the class currently being built. The type of
- the baseclass must be popped off the type stack. The arguments
- are the bit position, whether the class is virtual, and the
- visibility. */
- boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean,
- enum debug_visibility));
-
- /* Start adding a method to the class currently being built. This
- is followed by calls to class_method_variant and
- class_static_method_variant to describe different variants of the
- method which take different arguments. The method is finished
- with a call to class_end_method. The argument is the method
- name. */
- boolean (*class_start_method) PARAMS ((PTR, const char *));
-
- /* Describe a variant to the class method currently being built.
- The type of the variant must be popped off the type stack. The
- second argument is the physical name of the function. The
- following arguments are the visibility, whether the variant is
- const, whether the variant is volatile, the offset in the virtual
- function table, and whether the context is on the type stack
- (below the variant type). */
- boolean (*class_method_variant) PARAMS ((PTR, const char *,
- enum debug_visibility,
- boolean, boolean,
- bfd_vma, boolean));
-
- /* Describe a static variant to the class method currently being
- built. The arguments are the same as for class_method_variant,
- except that the last two arguments are omitted. The type of the
- variant must be popped off the type stack. */
- boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
- enum debug_visibility,
- boolean, boolean));
-
- /* Finish describing a class method. */
- boolean (*class_end_method) PARAMS ((PTR));
-
- /* Finish describing a class, and push it onto the type stack. */
- boolean (*end_class_type) PARAMS ((PTR));
-
- /* Push a type on the stack which was given a name by an earlier
- call to typdef. */
- boolean (*typedef_type) PARAMS ((PTR, const char *));
-
- /* Push a tagged type on the stack which was defined earlier. If
- the second argument is not NULL, the type was defined by a call
- to tag. If the second argument is NULL, the type was defined by
- a call to start_struct_type or start_class_type with a tag of
- NULL and the number of the third argument. Either way, the
- fourth argument is the tag kind. Note that this may be called
- for a struct (class) being defined, in between the call to
- start_struct_type (start_class_type) and the call to
- end_struct_type (end_class_type). */
- boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int,
- enum debug_type_kind));
-
- /* Pop the type stack, and typedef it to the given name. */
- boolean (*typdef) PARAMS ((PTR, const char *));
-
- /* Pop the type stack, and declare it as a tagged struct or union or
- enum or whatever. The tag passed down here is redundant, since
- was also passed when enum_type, start_struct_type, or
- start_class_type was called. */
- boolean (*tag) PARAMS ((PTR, const char *));
-
- /* This is called to record a named integer constant. */
- boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma));
-
- /* This is called to record a named floating point constant. */
- boolean (*float_constant) PARAMS ((PTR, const char *, double));
-
- /* This is called to record a typed integer constant. The type is
- popped off the type stack. */
- boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma));
-
- /* This is called to record a variable. The type is popped off the
- type stack. */
- boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind,
- bfd_vma));
-
- /* Start writing out a function. The return type must be popped off
- the stack. The boolean is true if the function is global. This
- is followed by calls to function_parameter, followed by block
- information. */
- boolean (*start_function) PARAMS ((PTR, const char *, boolean));
-
- /* Record a function parameter for the current function. The type
- must be popped off the stack. */
- boolean (*function_parameter) PARAMS ((PTR, const char *,
- enum debug_parm_kind, bfd_vma));
-
- /* Start writing out a block. There is at least one top level block
- per function. Blocks may be nested. The argument is the
- starting address of the block. */
- boolean (*start_block) PARAMS ((PTR, bfd_vma));
-
- /* Finish writing out a block. The argument is the ending address
- of the block. */
- boolean (*end_block) PARAMS ((PTR, bfd_vma));
-
- /* Finish writing out a function. */
- boolean (*end_function) PARAMS ((PTR));
-
- /* Record line number information for the current compilation unit. */
- boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
-};
-
-/* Exported functions. */
-
-/* The first argument to most of these functions is a handle. This
- handle is returned by the debug_init function. The purpose of the
- handle is to permit the debugging routines to not use static
- variables, and hence to be reentrant. This would be useful for a
- program which wanted to handle two executables simultaneously. */
-
-/* Return a debugging handle. */
-
-extern PTR debug_init PARAMS ((void));
-
-/* Set the source filename. This implicitly starts a new compilation
- unit. */
-
-extern boolean debug_set_filename PARAMS ((PTR, const char *));
-
-/* Change source files to the given file name. This is used for
- include files in a single compilation unit. */
-
-extern boolean debug_start_source PARAMS ((PTR, const char *));
-
-/* Record a function definition. This implicitly starts a function
- block. The debug_type argument is the type of the return value.
- The boolean indicates whether the function is globally visible.
- The bfd_vma is the address of the start of the function. Currently
- the parameter types are specified by calls to
- debug_record_parameter. */
-
-extern boolean debug_record_function
- PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma));
-
-/* Record a parameter for the current function. */
-
-extern boolean debug_record_parameter
- PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma));
-
-/* End a function definition. The argument is the address where the
- function ends. */
-
-extern boolean debug_end_function PARAMS ((PTR, bfd_vma));
-
-/* Start a block in a function. All local information will be
- recorded in this block, until the matching call to debug_end_block.
- debug_start_block and debug_end_block may be nested. The argument
- is the address at which this block starts. */
-
-extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
-
-/* Finish a block in a function. This matches the call to
- debug_start_block. The argument is the address at which this block
- ends. */
-
-extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
-
-/* Associate a line number in the current source file with a given
- address. */
-
-extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
-
-/* Start a named common block. This is a block of variables that may
- move in memory. */
-
-extern boolean debug_start_common_block PARAMS ((PTR, const char *));
-
-/* End a named common block. */
-
-extern boolean debug_end_common_block PARAMS ((PTR, const char *));
-
-/* Record a named integer constant. */
-
-extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma));
-
-/* Record a named floating point constant. */
-
-extern boolean debug_record_float_const PARAMS ((PTR, const char *, double));
-
-/* Record a typed constant with an integral value. */
-
-extern boolean debug_record_typed_const
- PARAMS ((PTR, const char *, debug_type, bfd_vma));
-
-/* Record a label. */
-
-extern boolean debug_record_label
- PARAMS ((PTR, const char *, debug_type, bfd_vma));
-
-/* Record a variable. */
-
-extern boolean debug_record_variable
- PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma));
-
-/* Make an indirect type. The first argument is a pointer to the
- location where the real type will be placed. The second argument
- is the type tag, if there is one; this may be NULL; the only
- purpose of this argument is so that debug_get_type_name can return
- something useful. This function may be used when a type is
- referenced before it is defined. */
-
-extern debug_type debug_make_indirect_type
- PARAMS ((PTR, debug_type *, const char *));
-
-/* Make a void type. */
-
-extern debug_type debug_make_void_type PARAMS ((PTR));
-
-/* Make an integer type of a given size. The boolean argument is true
- if the integer is unsigned. */
-
-extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean));
-
-/* Make a floating point type of a given size. FIXME: On some
- platforms, like an Alpha, you probably need to be able to specify
- the format. */
-
-extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int));
-
-/* Make a boolean type of a given size. */
-
-extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int));
-
-/* Make a complex type of a given size. */
-
-extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int));
-
-/* Make a structure type. The second argument is true for a struct,
- false for a union. The third argument is the size of the struct.
- The fourth argument is a NULL terminated array of fields. */
-
-extern debug_type debug_make_struct_type
- PARAMS ((PTR, boolean, bfd_vma, debug_field *));
-
-/* Make an object type. The first three arguments after the handle
- are the same as for debug_make_struct_type. The next arguments are
- a NULL terminated array of base classes, a NULL terminated array of
- methods, the type of the object holding the virtual function table
- if it is not this object, and a boolean which is true if this
- object has its own virtual function table. */
-
-extern debug_type debug_make_object_type
- PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *,
- debug_method *, debug_type, boolean));
-
-/* Make an enumeration type. The arguments are a null terminated
- array of strings, and an array of corresponding values. */
-
-extern debug_type debug_make_enum_type
- PARAMS ((PTR, const char **, bfd_signed_vma *));
-
-/* Make a pointer to a given type. */
-
-extern debug_type debug_make_pointer_type
- PARAMS ((PTR, debug_type));
-
-/* Make a function type. The second argument is the return type. The
- third argument is a NULL terminated array of argument types. The
- fourth argument is true if the function takes a variable number of
- arguments. If the third argument is NULL, then the argument types
- are unknown. */
-
-extern debug_type debug_make_function_type
- PARAMS ((PTR, debug_type, debug_type *, boolean));
-
-/* Make a reference to a given type. */
-
-extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type));
-
-/* Make a range of a given type from a lower to an upper bound. */
-
-extern debug_type debug_make_range_type
- PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma));
-
-/* Make an array type. The second argument is the type of an element
- of the array. The third argument is the type of a range of the
- array. The fourth and fifth argument are the lower and upper
- bounds, respectively (if the bounds are not known, lower should be
- 0 and upper should be -1). The sixth argument is true if this
- array is actually a string, as in C. */
-
-extern debug_type debug_make_array_type
- PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma,
- boolean));
-
-/* Make a set of a given type. For example, a Pascal set type. The
- boolean argument is true if this set is actually a bitstring, as in
- CHILL. */
-
-extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean));
-
-/* Make a type for a pointer which is relative to an object. The
- second argument is the type of the object to which the pointer is
- relative. The third argument is the type that the pointer points
- to. */
-
-extern debug_type debug_make_offset_type
- PARAMS ((PTR, debug_type, debug_type));
-
-/* Make a type for a method function. The second argument is the
- return type. The third argument is the domain. The fourth
- argument is a NULL terminated array of argument types. The fifth
- argument is true if the function takes a variable number of
- arguments, in which case the array of argument types indicates the
- types of the first arguments. The domain and the argument array
- may be NULL, in which case this is a stub method and that
- information is not available. Stabs debugging uses this, and gets
- the argument types from the mangled name. */
-
-extern debug_type debug_make_method_type
- PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
-
-/* Make a const qualified version of a given type. */
-
-extern debug_type debug_make_const_type PARAMS ((PTR, debug_type));
-
-/* Make a volatile qualified version of a given type. */
-
-extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type));
-
-/* Make an undefined tagged type. For example, a struct which has
- been mentioned, but not defined. */
-
-extern debug_type debug_make_undefined_tagged_type
- PARAMS ((PTR, const char *, enum debug_type_kind));
-
-/* Make a base class for an object. The second argument is the base
- class type. The third argument is the bit position of this base
- class in the object. The fourth argument is whether this is a
- virtual class. The fifth argument is the visibility of the base
- class. */
-
-extern debug_baseclass debug_make_baseclass
- PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility));
-
-/* Make a field for a struct. The second argument is the name. The
- third argument is the type of the field. The fourth argument is
- the bit position of the field. The fifth argument is the size of
- the field (it may be zero). The sixth argument is the visibility
- of the field. */
-
-extern debug_field debug_make_field
- PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma,
- enum debug_visibility));
-
-/* Make a static member of an object. The second argument is the
- name. The third argument is the type of the member. The fourth
- argument is the physical name of the member (i.e., the name as a
- global variable). The fifth argument is the visibility of the
- member. */
-
-extern debug_field debug_make_static_member
- PARAMS ((PTR, const char *, debug_type, const char *,
- enum debug_visibility));
-
-/* Make a method. The second argument is the name, and the third
- argument is a NULL terminated array of method variants. Each
- method variant is a method with this name but with different
- argument types. */
-
-extern debug_method debug_make_method
- PARAMS ((PTR, const char *, debug_method_variant *));
-
-/* Make a method variant. The second argument is the physical name of
- the function. The third argument is the type of the function,
- probably constructed by debug_make_method_type. The fourth
- argument is the visibility. The fifth argument is whether this is
- a const function. The sixth argument is whether this is a volatile
- function. The seventh argument is the index in the virtual
- function table, if any. The eighth argument is the virtual
- function context. */
-
-extern debug_method_variant debug_make_method_variant
- PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
- boolean, bfd_vma, debug_type));
-
-/* Make a static method argument. The arguments are the same as for
- debug_make_method_variant, except that the last two are omitted
- since a static method can not also be virtual. */
-
-extern debug_method_variant debug_make_static_method_variant
- PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
- boolean));
-
-/* Name a type. This returns a new type with an attached name. */
-
-extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type));
-
-/* Give a tag to a type, such as a struct or union. This returns a
- new type with an attached tag. */
-
-extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type));
-
-/* Record the size of a given type. */
-
-extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int));
-
-/* Find a named type. */
-
-extern debug_type debug_find_named_type PARAMS ((PTR, const char *));
-
-/* Find a tagged type. */
-
-extern debug_type debug_find_tagged_type
- PARAMS ((PTR, const char *, enum debug_type_kind));
-
-/* Get the kind of a type. */
-
-extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type));
-
-/* Get the name of a type. */
-
-extern const char *debug_get_type_name PARAMS ((PTR, debug_type));
-
-/* Get the size of a type. */
-
-extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type));
-
-/* Get the return type of a function or method type. */
-
-extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
-
-/* Get the NULL terminated array of parameter types for a function or
- method type (actually, parameter types are not currently stored for
- function types). This may be used to determine whether a method
- type is a stub method or not. The last argument points to a
- boolean which is set to true if the function takes a variable
- number of arguments. */
-
-extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
- debug_type,
- boolean *));
-
-/* Get the target type of a pointer or reference or const or volatile
- type. */
-
-extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
-
-/* Get the NULL terminated array of fields for a struct, union, or
- class. */
-
-extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type));
-
-/* Get the type of a field. */
-
-extern debug_type debug_get_field_type PARAMS ((PTR, debug_field));
-
-/* Get the name of a field. */
-
-extern const char *debug_get_field_name PARAMS ((PTR, debug_field));
-
-/* Get the bit position of a field within the containing structure.
- If the field is a static member, this will return (bfd_vma) -1. */
-
-extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field));
-
-/* Get the bit size of a field. If the field is a static member, this
- will return (bfd_vma) -1. */
-
-extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field));
-
-/* Get the visibility of a field. */
-
-extern enum debug_visibility debug_get_field_visibility
- PARAMS ((PTR, debug_field));
-
-/* Get the physical name of a field, if it is a static member. If the
- field is not a static member, this will return NULL. */
-
-extern const char *debug_get_field_physname PARAMS ((PTR, debug_field));
-
-/* Write out the recorded debugging information. This takes a set of
- function pointers which are called to do the actual writing. The
- first PTR is the debugging handle. The second PTR is a handle
- which is passed to the functions. */
-
-extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR));
-
-#endif /* DEBUG_H */
diff --git a/pstack/demangle.h b/pstack/demangle.h
deleted file mode 100644
index a961436ca77..00000000000
--- a/pstack/demangle.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Defs for interface to demanglers.
- Copyright 1992, 1995, 1996 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-
-#if !defined (DEMANGLE_H)
-#define DEMANGLE_H
-
-#ifdef IN_GCC
-#include "gansidecl.h"
-#define PARAMS(ARGS) PROTO(ARGS)
-#else /* ! IN_GCC */
-#include <ansidecl.h>
-#endif /* IN_GCC */
-
-/* Options passed to cplus_demangle (in 2nd parameter). */
-
-#define DMGL_NO_OPTS 0 /* For readability... */
-#define DMGL_PARAMS (1 << 0) /* Include function args */
-#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-
-#define DMGL_AUTO (1 << 8)
-#define DMGL_GNU (1 << 9)
-#define DMGL_LUCID (1 << 10)
-#define DMGL_ARM (1 << 11)
-/* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM)
-
-/* Enumeration of possible demangling styles.
-
- Lucid and ARM styles are still kept logically distinct, even though
- they now both behave identically. The resulting style is actual the
- union of both. I.E. either style recognizes both "__pt__" and "__rf__"
- for operator "->", even though the first is lucid style and the second
- is ARM style. (FIXME?) */
-
-extern enum demangling_styles
-{
- unknown_demangling = 0,
- auto_demangling = DMGL_AUTO,
- gnu_demangling = DMGL_GNU,
- lucid_demangling = DMGL_LUCID,
- arm_demangling = DMGL_ARM
-} current_demangling_style;
-
-/* Define string names for the various demangling styles. */
-
-#define AUTO_DEMANGLING_STYLE_STRING "auto"
-#define GNU_DEMANGLING_STYLE_STRING "gnu"
-#define LUCID_DEMANGLING_STYLE_STRING "lucid"
-#define ARM_DEMANGLING_STYLE_STRING "arm"
-
-/* Some macros to test what demangling style is active. */
-
-#define CURRENT_DEMANGLING_STYLE current_demangling_style
-#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
-#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
-#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
-#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM)
-
-extern char *
-cplus_demangle PARAMS ((const char *mangled, int options));
-
-extern int
-cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
-
-extern const char *
-cplus_mangle_opname PARAMS ((const char *opname, int options));
-
-/* Note: This sets global state. FIXME if you care about multi-threading. */
-
-extern void
-set_cplus_marker_for_demangling PARAMS ((int ch));
-
-#endif /* DEMANGLE_H */
diff --git a/pstack/filemode.c b/pstack/filemode.c
deleted file mode 100644
index 58b52ba7489..00000000000
--- a/pstack/filemode.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* filemode.c -- make a string describing file modes
- Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#include "bfd.h"
-#include "bucomm.h"
-
-static char ftypelet PARAMS ((unsigned long));
-static void setst PARAMS ((unsigned long, char *));
-
-/* filemodestring - fill in string STR with an ls-style ASCII
- representation of the st_mode field of file stats block STATP.
- 10 characters are stored in STR; no terminating null is added.
- The characters stored in STR are:
-
- 0 File type. 'd' for directory, 'c' for character
- special, 'b' for block special, 'm' for multiplex,
- 'l' for symbolic link, 's' for socket, 'p' for fifo,
- '-' for any other file type
-
- 1 'r' if the owner may read, '-' otherwise.
-
- 2 'w' if the owner may write, '-' otherwise.
-
- 3 'x' if the owner may execute, 's' if the file is
- set-user-id, '-' otherwise.
- 'S' if the file is set-user-id, but the execute
- bit isn't set.
-
- 4 'r' if group members may read, '-' otherwise.
-
- 5 'w' if group members may write, '-' otherwise.
-
- 6 'x' if group members may execute, 's' if the file is
- set-group-id, '-' otherwise.
- 'S' if it is set-group-id but not executable.
-
- 7 'r' if any user may read, '-' otherwise.
-
- 8 'w' if any user may write, '-' otherwise.
-
- 9 'x' if any user may execute, 't' if the file is "sticky"
- (will be retained in swap space after execution), '-'
- otherwise.
- 'T' if the file is sticky but not executable. */
-
-#if 0
-
-/* This is not used; only mode_string is used. */
-
-void
-filemodestring (statp, str)
- struct stat *statp;
- char *str;
-{
- mode_string ((unsigned long) statp->st_mode, str);
-}
-
-#endif
-
-/* Get definitions for the file permission bits. */
-
-#ifndef S_IRWXU
-#define S_IRWXU 0700
-#endif
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#endif
-#ifndef S_IWUSR
-#define S_IWUSR 0200
-#endif
-#ifndef S_IXUSR
-#define S_IXUSR 0100
-#endif
-
-#ifndef S_IRWXG
-#define S_IRWXG 0070
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP 0040
-#endif
-#ifndef S_IWGRP
-#define S_IWGRP 0020
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 0010
-#endif
-
-#ifndef S_IRWXO
-#define S_IRWXO 0007
-#endif
-#ifndef S_IROTH
-#define S_IROTH 0004
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 0002
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 0001
-#endif
-
-/* Like filemodestring, but only the relevant part of the `struct stat'
- is given as an argument. */
-
-void
-mode_string (mode, str)
- unsigned long mode;
- char *str;
-{
- str[0] = ftypelet ((unsigned long) mode);
- str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
- str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
- str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
- str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
- str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
- str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
- str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
- str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
- str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
- setst ((unsigned long) mode, str);
-}
-
-/* Return a character indicating the type of file described by
- file mode BITS:
- 'd' for directories
- 'b' for block special files
- 'c' for character special files
- 'm' for multiplexor files
- 'l' for symbolic links
- 's' for sockets
- 'p' for fifos
- '-' for any other file type. */
-
-#ifndef S_ISDIR
-#ifdef S_IFDIR
-#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
-#else /* ! defined (S_IFDIR) */
-#define S_ISDIR(i) (((i) & 0170000) == 040000)
-#endif /* ! defined (S_IFDIR) */
-#endif /* ! defined (S_ISDIR) */
-
-#ifndef S_ISBLK
-#ifdef S_IFBLK
-#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
-#else /* ! defined (S_IFBLK) */
-#define S_ISBLK(i) 0
-#endif /* ! defined (S_IFBLK) */
-#endif /* ! defined (S_ISBLK) */
-
-#ifndef S_ISCHR
-#ifdef S_IFCHR
-#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
-#else /* ! defined (S_IFCHR) */
-#define S_ISCHR(i) 0
-#endif /* ! defined (S_IFCHR) */
-#endif /* ! defined (S_ISCHR) */
-
-#ifndef S_ISFIFO
-#ifdef S_IFIFO
-#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
-#else /* ! defined (S_IFIFO) */
-#define S_ISFIFO(i) 0
-#endif /* ! defined (S_IFIFO) */
-#endif /* ! defined (S_ISFIFO) */
-
-#ifndef S_ISSOCK
-#ifdef S_IFSOCK
-#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
-#else /* ! defined (S_IFSOCK) */
-#define S_ISSOCK(i) 0
-#endif /* ! defined (S_IFSOCK) */
-#endif /* ! defined (S_ISSOCK) */
-
-#ifndef S_ISLNK
-#ifdef S_IFLNK
-#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
-#else /* ! defined (S_IFLNK) */
-#define S_ISLNK(i) 0
-#endif /* ! defined (S_IFLNK) */
-#endif /* ! defined (S_ISLNK) */
-
-static char
-ftypelet (bits)
- unsigned long bits;
-{
- if (S_ISDIR (bits))
- return 'd';
- if (S_ISLNK (bits))
- return 'l';
- if (S_ISBLK (bits))
- return 'b';
- if (S_ISCHR (bits))
- return 'c';
- if (S_ISSOCK (bits))
- return 's';
- if (S_ISFIFO (bits))
- return 'p';
-
-#ifdef S_IFMT
-#ifdef S_IFMPC
- if ((bits & S_IFMT) == S_IFMPC
- || (bits & S_IFMT) == S_IFMPB)
- return 'm';
-#endif
-#ifdef S_IFNWK
- if ((bits & S_IFMT) == S_IFNWK)
- return 'n';
-#endif
-#endif
-
- return '-';
-}
-
-/* Set the 's' and 't' flags in file attributes string CHARS,
- according to the file mode BITS. */
-
-static void
-setst (bits, chars)
- unsigned long bits;
- char *chars;
-{
-#ifdef S_ISUID
- if (bits & S_ISUID)
- {
- if (chars[3] != 'x')
- /* Set-uid, but not executable by owner. */
- chars[3] = 'S';
- else
- chars[3] = 's';
- }
-#endif
-#ifdef S_ISGID
- if (bits & S_ISGID)
- {
- if (chars[6] != 'x')
- /* Set-gid, but not executable by group. */
- chars[6] = 'S';
- else
- chars[6] = 's';
- }
-#endif
-#ifdef S_ISVTX
- if (bits & S_ISVTX)
- {
- if (chars[9] != 'x')
- /* Sticky, but not executable by others. */
- chars[9] = 'T';
- else
- chars[9] = 't';
- }
-#endif
-}
diff --git a/pstack/ieee.c b/pstack/ieee.c
deleted file mode 100644
index 8084656a5ef..00000000000
--- a/pstack/ieee.c
+++ /dev/null
@@ -1,7602 +0,0 @@
-/* ieee.c -- Read and write IEEE-695 debugging information.
- Copyright (C) 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file reads and writes IEEE-695 debugging information. */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <bfd.h>
-#include "ieee.h"
-#include "bucomm.h"
-#include <libiberty.h>
-#include "debug.h"
-#include "budbg.h"
-
-/* This structure holds an entry on the block stack. */
-
-struct ieee_block
-{
- /* The kind of block. */
- int kind;
- /* The source file name, for a BB5 block. */
- const char *filename;
- /* The index of the function type, for a BB4 or BB6 block. */
- unsigned int fnindx;
- /* True if this function is being skipped. */
- boolean skip;
-};
-
-/* This structure is the block stack. */
-
-#define BLOCKSTACK_SIZE (16)
-
-struct ieee_blockstack
-{
- /* The stack pointer. */
- struct ieee_block *bsp;
- /* The stack. */
- struct ieee_block stack[BLOCKSTACK_SIZE];
-};
-
-/* This structure holds information for a variable. */
-
-struct ieee_var
-{
- /* Start of name. */
- const char *name;
- /* Length of name. */
- unsigned long namlen;
- /* Type. */
- debug_type type;
- /* Slot if we make an indirect type. */
- debug_type *pslot;
- /* Kind of variable or function. */
- enum
- {
- IEEE_UNKNOWN,
- IEEE_EXTERNAL,
- IEEE_GLOBAL,
- IEEE_STATIC,
- IEEE_LOCAL,
- IEEE_FUNCTION
- } kind;
-};
-
-/* This structure holds all the variables. */
-
-struct ieee_vars
-{
- /* Number of slots allocated. */
- unsigned int alloc;
- /* Variables. */
- struct ieee_var *vars;
-};
-
-/* This structure holds information for a type. We need this because
- we don't want to represent bitfields as real types. */
-
-struct ieee_type
-{
- /* Type. */
- debug_type type;
- /* Slot if this is type is referenced before it is defined. */
- debug_type *pslot;
- /* Slots for arguments if we make indirect types for them. */
- debug_type *arg_slots;
- /* If this is a bitfield, this is the size in bits. If this is not
- a bitfield, this is zero. */
- unsigned long bitsize;
-};
-
-/* This structure holds all the type information. */
-
-struct ieee_types
-{
- /* Number of slots allocated. */
- unsigned int alloc;
- /* Types. */
- struct ieee_type *types;
- /* Builtin types. */
-#define BUILTIN_TYPE_COUNT (60)
- debug_type builtins[BUILTIN_TYPE_COUNT];
-};
-
-/* This structure holds a linked last of structs with their tag names,
- so that we can convert them to C++ classes if necessary. */
-
-struct ieee_tag
-{
- /* Next tag. */
- struct ieee_tag *next;
- /* This tag name. */
- const char *name;
- /* The type of the tag. */
- debug_type type;
- /* The tagged type is an indirect type pointing at this slot. */
- debug_type slot;
- /* This is an array of slots used when a field type is converted
- into a indirect type, in case it needs to be later converted into
- a reference type. */
- debug_type *fslots;
-};
-
-/* This structure holds the information we pass around to the parsing
- functions. */
-
-struct ieee_info
-{
- /* The debugging handle. */
- PTR dhandle;
- /* The BFD. */
- bfd *abfd;
- /* The start of the bytes to be parsed. */
- const bfd_byte *bytes;
- /* The end of the bytes to be parsed. */
- const bfd_byte *pend;
- /* The block stack. */
- struct ieee_blockstack blockstack;
- /* Whether we have seen a BB1 or BB2. */
- boolean saw_filename;
- /* The variables. */
- struct ieee_vars vars;
- /* The global variables, after a global typedef block. */
- struct ieee_vars *global_vars;
- /* The types. */
- struct ieee_types types;
- /* The global types, after a global typedef block. */
- struct ieee_types *global_types;
- /* The list of tagged structs. */
- struct ieee_tag *tags;
-};
-
-/* Basic builtin types, not including the pointers. */
-
-enum builtin_types
-{
- builtin_unknown = 0,
- builtin_void = 1,
- builtin_signed_char = 2,
- builtin_unsigned_char = 3,
- builtin_signed_short_int = 4,
- builtin_unsigned_short_int = 5,
- builtin_signed_long = 6,
- builtin_unsigned_long = 7,
- builtin_signed_long_long = 8,
- builtin_unsigned_long_long = 9,
- builtin_float = 10,
- builtin_double = 11,
- builtin_long_double = 12,
- builtin_long_long_double = 13,
- builtin_quoted_string = 14,
- builtin_instruction_address = 15,
- builtin_int = 16,
- builtin_unsigned = 17,
- builtin_unsigned_int = 18,
- builtin_char = 19,
- builtin_long = 20,
- builtin_short = 21,
- builtin_unsigned_short = 22,
- builtin_short_int = 23,
- builtin_signed_short = 24,
- builtin_bcd_float = 25
-};
-
-/* These are the values found in the derivation flags of a 'b'
- component record of a 'T' type extension record in a C++ pmisc
- record. These are bitmasks. */
-
-/* Set for a private base class, clear for a public base class.
- Protected base classes are not supported. */
-#define BASEFLAGS_PRIVATE (0x1)
-/* Set for a virtual base class. */
-#define BASEFLAGS_VIRTUAL (0x2)
-/* Set for a friend class, clear for a base class. */
-#define BASEFLAGS_FRIEND (0x10)
-
-/* These are the values found in the specs flags of a 'd', 'm', or 'v'
- component record of a 'T' type extension record in a C++ pmisc
- record. The same flags are used for a 'M' record in a C++ pmisc
- record. */
-
-/* The lower two bits hold visibility information. */
-#define CXXFLAGS_VISIBILITY (0x3)
-/* This value in the lower two bits indicates a public member. */
-#define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
-/* This value in the lower two bits indicates a private member. */
-#define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
-/* This value in the lower two bits indicates a protected member. */
-#define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
-/* Set for a static member. */
-#define CXXFLAGS_STATIC (0x4)
-/* Set for a virtual override. */
-#define CXXFLAGS_OVERRIDE (0x8)
-/* Set for a friend function. */
-#define CXXFLAGS_FRIEND (0x10)
-/* Set for a const function. */
-#define CXXFLAGS_CONST (0x20)
-/* Set for a volatile function. */
-#define CXXFLAGS_VOLATILE (0x40)
-/* Set for an overloaded function. */
-#define CXXFLAGS_OVERLOADED (0x80)
-/* Set for an operator function. */
-#define CXXFLAGS_OPERATOR (0x100)
-/* Set for a constructor or destructor. */
-#define CXXFLAGS_CTORDTOR (0x400)
-/* Set for a constructor. */
-#define CXXFLAGS_CTOR (0x200)
-/* Set for an inline function. */
-#define CXXFLAGS_INLINE (0x800)
-
-/* Local functions. */
-
-static void ieee_error
- PARAMS ((struct ieee_info *, const bfd_byte *, const char *));
-static void ieee_eof PARAMS ((struct ieee_info *));
-static char *savestring PARAMS ((const char *, unsigned long));
-static boolean ieee_read_number
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
-static boolean ieee_read_optional_number
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *));
-static boolean ieee_read_id
- PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
- unsigned long *));
-static boolean ieee_read_optional_id
- PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
- unsigned long *, boolean *));
-static boolean ieee_read_expression
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
-static debug_type ieee_builtin_type
- PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int));
-static boolean ieee_alloc_type
- PARAMS ((struct ieee_info *, unsigned int, boolean));
-static boolean ieee_read_type_index
- PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *));
-static int ieee_regno_to_genreg PARAMS ((bfd *, int));
-static int ieee_genreg_to_regno PARAMS ((bfd *, int));
-static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean ieee_read_cxx_misc
- PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
-static boolean ieee_read_cxx_class
- PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
-static boolean ieee_read_cxx_defaults
- PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
-static boolean ieee_read_reference
- PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean ieee_require_asn
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
-static boolean ieee_require_atn65
- PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
- unsigned long *));
-
-/* Report an error in the IEEE debugging information. */
-
-static void
-ieee_error (info, p, s)
- struct ieee_info *info;
- const bfd_byte *p;
- const char *s;
-{
- if (p != NULL)
- fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
- (unsigned long) (p - info->bytes), s, *p);
- else
- fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
-}
-
-/* Report an unexpected EOF in the IEEE debugging information. */
-
-static void
-ieee_eof (info)
- struct ieee_info *info;
-{
- ieee_error (info, (const bfd_byte *) NULL,
- "unexpected end of debugging information");
-}
-
-/* Save a string in memory. */
-
-static char *
-savestring (start, len)
- const char *start;
- unsigned long len;
-{
- char *ret;
-
- ret = (char *) xmalloc (len + 1);
- memcpy (ret, start, len);
- ret[len] = '\0';
- return ret;
-}
-
-/* Read a number which must be present in an IEEE file. */
-
-static boolean
-ieee_read_number (info, pp, pv)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
-{
- return ieee_read_optional_number (info, pp, pv, (boolean *) NULL);
-}
-
-/* Read a number in an IEEE file. If ppresent is not NULL, the number
- need not be there. */
-
-static boolean
-ieee_read_optional_number (info, pp, pv, ppresent)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
- boolean *ppresent;
-{
- ieee_record_enum_type b;
-
- if (*pp >= info->pend)
- {
- if (ppresent != NULL)
- {
- *ppresent = false;
- return true;
- }
- ieee_eof (info);
- return false;
- }
-
- b = (ieee_record_enum_type) **pp;
- ++*pp;
-
- if (b <= ieee_number_end_enum)
- {
- *pv = (bfd_vma) b;
- if (ppresent != NULL)
- *ppresent = true;
- return true;
- }
-
- if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
- {
- unsigned int i;
-
- i = (int) b - (int) ieee_number_repeat_start_enum;
- if (*pp + i - 1 >= info->pend)
- {
- ieee_eof (info);
- return false;
- }
-
- *pv = 0;
- for (; i > 0; i--)
- {
- *pv <<= 8;
- *pv += **pp;
- ++*pp;
- }
-
- if (ppresent != NULL)
- *ppresent = true;
-
- return true;
- }
-
- if (ppresent != NULL)
- {
- --*pp;
- *ppresent = false;
- return true;
- }
-
- ieee_error (info, *pp - 1, "invalid number");
- return false;
-}
-
-/* Read a required string from an IEEE file. */
-
-static boolean
-ieee_read_id (info, pp, pname, pnamlen)
- struct ieee_info *info;
- const bfd_byte **pp;
- const char **pname;
- unsigned long *pnamlen;
-{
- return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL);
-}
-
-/* Read a string from an IEEE file. If ppresent is not NULL, the
- string is optional. */
-
-static boolean
-ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
- struct ieee_info *info;
- const bfd_byte **pp;
- const char **pname;
- unsigned long *pnamlen;
- boolean *ppresent;
-{
- bfd_byte b;
- unsigned long len;
-
- if (*pp >= info->pend)
- {
- ieee_eof (info);
- return false;
- }
-
- b = **pp;
- ++*pp;
-
- if (b <= 0x7f)
- len = b;
- else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
- {
- len = **pp;
- ++*pp;
- }
- else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
- {
- len = (**pp << 8) + (*pp)[1];
- *pp += 2;
- }
- else
- {
- if (ppresent != NULL)
- {
- --*pp;
- *ppresent = false;
- return true;
- }
- ieee_error (info, *pp - 1, "invalid string length");
- return false;
- }
-
- if ((unsigned long) (info->pend - *pp) < len)
- {
- ieee_eof (info);
- return false;
- }
-
- *pname = (const char *) *pp;
- *pnamlen = len;
- *pp += len;
-
- if (ppresent != NULL)
- *ppresent = true;
-
- return true;
-}
-
-/* Read an expression from an IEEE file. Since this code is only used
- to parse debugging information, I haven't bothered to write a full
- blown IEEE expression parser. I've only thrown in the things I've
- seen in debugging information. This can be easily extended if
- necessary. */
-
-static boolean
-ieee_read_expression (info, pp, pv)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
-{
- const bfd_byte *expr_start;
-#define EXPR_STACK_SIZE (10)
- bfd_vma expr_stack[EXPR_STACK_SIZE];
- bfd_vma *esp;
-
- expr_start = *pp;
-
- esp = expr_stack;
-
- while (1)
- {
- const bfd_byte *start;
- bfd_vma val;
- boolean present;
- ieee_record_enum_type c;
-
- start = *pp;
-
- if (! ieee_read_optional_number (info, pp, &val, &present))
- return false;
-
- if (present)
- {
- if (esp - expr_stack >= EXPR_STACK_SIZE)
- {
- ieee_error (info, start, "expression stack overflow");
- return false;
- }
- *esp++ = val;
- continue;
- }
-
- c = (ieee_record_enum_type) **pp;
-
- if (c >= ieee_module_beginning_enum)
- break;
-
- ++*pp;
-
- if (c == ieee_comma)
- break;
-
- switch (c)
- {
- default:
- ieee_error (info, start, "unsupported IEEE expression operator");
- break;
-
- case ieee_variable_R_enum:
- {
- bfd_vma indx;
- asection *s;
-
- if (! ieee_read_number (info, pp, &indx))
- return false;
- for (s = info->abfd->sections; s != NULL; s = s->next)
- if ((bfd_vma) s->target_index == indx)
- break;
- if (s == NULL)
- {
- ieee_error (info, start, "unknown section");
- return false;
- }
-
- if (esp - expr_stack >= EXPR_STACK_SIZE)
- {
- ieee_error (info, start, "expression stack overflow");
- return false;
- }
-
- *esp++ = bfd_get_section_vma (info->abfd, s);
- }
- break;
-
- case ieee_function_plus_enum:
- case ieee_function_minus_enum:
- {
- bfd_vma v1, v2;
-
- if (esp - expr_stack < 2)
- {
- ieee_error (info, start, "expression stack underflow");
- return false;
- }
-
- v1 = *--esp;
- v2 = *--esp;
- *esp++ = v1 + v2;
- }
- break;
- }
- }
-
- if (esp - 1 != expr_stack)
- {
- ieee_error (info, expr_start, "expression stack mismatch");
- return false;
- }
-
- *pv = *--esp;
-
- return true;
-}
-
-/* Return an IEEE builtin type. */
-
-static debug_type
-ieee_builtin_type (info, p, indx)
- struct ieee_info *info;
- const bfd_byte *p;
- unsigned int indx;
-{
- PTR dhandle;
- debug_type type;
- const char *name;
-
- if (indx < BUILTIN_TYPE_COUNT
- && info->types.builtins[indx] != DEBUG_TYPE_NULL)
- return info->types.builtins[indx];
-
- dhandle = info->dhandle;
-
- if (indx >= 32 && indx < 64)
- {
- type = debug_make_pointer_type (dhandle,
- ieee_builtin_type (info, p, indx - 32));
- assert (indx < BUILTIN_TYPE_COUNT);
- info->types.builtins[indx] = type;
- return type;
- }
-
- switch ((enum builtin_types) indx)
- {
- default:
- ieee_error (info, p, "unknown builtin type");
- return NULL;
-
- case builtin_unknown:
- type = debug_make_void_type (dhandle);
- name = NULL;
- break;
-
- case builtin_void:
- type = debug_make_void_type (dhandle);
- name = "void";
- break;
-
- case builtin_signed_char:
- type = debug_make_int_type (dhandle, 1, false);
- name = "signed char";
- break;
-
- case builtin_unsigned_char:
- type = debug_make_int_type (dhandle, 1, true);
- name = "unsigned char";
- break;
-
- case builtin_signed_short_int:
- type = debug_make_int_type (dhandle, 2, false);
- name = "signed short int";
- break;
-
- case builtin_unsigned_short_int:
- type = debug_make_int_type (dhandle, 2, true);
- name = "unsigned short int";
- break;
-
- case builtin_signed_long:
- type = debug_make_int_type (dhandle, 4, false);
- name = "signed long";
- break;
-
- case builtin_unsigned_long:
- type = debug_make_int_type (dhandle, 4, true);
- name = "unsigned long";
- break;
-
- case builtin_signed_long_long:
- type = debug_make_int_type (dhandle, 8, false);
- name = "signed long long";
- break;
-
- case builtin_unsigned_long_long:
- type = debug_make_int_type (dhandle, 8, true);
- name = "unsigned long long";
- break;
-
- case builtin_float:
- type = debug_make_float_type (dhandle, 4);
- name = "float";
- break;
-
- case builtin_double:
- type = debug_make_float_type (dhandle, 8);
- name = "double";
- break;
-
- case builtin_long_double:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_float_type (dhandle, 12);
- name = "long double";
- break;
-
- case builtin_long_long_double:
- type = debug_make_float_type (dhandle, 16);
- name = "long long double";
- break;
-
- case builtin_quoted_string:
- type = debug_make_array_type (dhandle,
- ieee_builtin_type (info, p,
- ((unsigned int)
- builtin_char)),
- ieee_builtin_type (info, p,
- ((unsigned int)
- builtin_int)),
- 0, -1, true);
- name = "QUOTED STRING";
- break;
-
- case builtin_instruction_address:
- /* FIXME: This should be a code address. */
- type = debug_make_int_type (dhandle, 4, true);
- name = "instruction address";
- break;
-
- case builtin_int:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_int_type (dhandle, 4, false);
- name = "int";
- break;
-
- case builtin_unsigned:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_int_type (dhandle, 4, true);
- name = "unsigned";
- break;
-
- case builtin_unsigned_int:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_int_type (dhandle, 4, true);
- name = "unsigned int";
- break;
-
- case builtin_char:
- type = debug_make_int_type (dhandle, 1, false);
- name = "char";
- break;
-
- case builtin_long:
- type = debug_make_int_type (dhandle, 4, false);
- name = "long";
- break;
-
- case builtin_short:
- type = debug_make_int_type (dhandle, 2, false);
- name = "short";
- break;
-
- case builtin_unsigned_short:
- type = debug_make_int_type (dhandle, 2, true);
- name = "unsigned short";
- break;
-
- case builtin_short_int:
- type = debug_make_int_type (dhandle, 2, false);
- name = "short int";
- break;
-
- case builtin_signed_short:
- type = debug_make_int_type (dhandle, 2, false);
- name = "signed short";
- break;
-
- case builtin_bcd_float:
- ieee_error (info, p, "BCD float type not supported");
- return DEBUG_TYPE_NULL;
- }
-
- if (name != NULL)
- type = debug_name_type (dhandle, name, type);
-
- assert (indx < BUILTIN_TYPE_COUNT);
-
- info->types.builtins[indx] = type;
-
- return type;
-}
-
-/* Allocate more space in the type table. If ref is true, this is a
- reference to the type; if it is not already defined, we should set
- up an indirect type. */
-
-static boolean
-ieee_alloc_type (info, indx, ref)
- struct ieee_info *info;
- unsigned int indx;
- boolean ref;
-{
- unsigned int nalloc;
- register struct ieee_type *t;
- struct ieee_type *tend;
-
- if (indx >= info->types.alloc)
- {
- nalloc = info->types.alloc;
- if (nalloc == 0)
- nalloc = 4;
- while (indx >= nalloc)
- nalloc *= 2;
-
- info->types.types = ((struct ieee_type *)
- xrealloc (info->types.types,
- nalloc * sizeof *info->types.types));
-
- memset (info->types.types + info->types.alloc, 0,
- (nalloc - info->types.alloc) * sizeof *info->types.types);
-
- tend = info->types.types + nalloc;
- for (t = info->types.types + info->types.alloc; t < tend; t++)
- t->type = DEBUG_TYPE_NULL;
-
- info->types.alloc = nalloc;
- }
-
- if (ref)
- {
- t = info->types.types + indx;
- if (t->type == NULL)
- {
- t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
- *t->pslot = DEBUG_TYPE_NULL;
- t->type = debug_make_indirect_type (info->dhandle, t->pslot,
- (const char *) NULL);
- if (t->type == NULL)
- return false;
- }
- }
-
- return true;
-}
-
-/* Read a type index and return the corresponding type. */
-
-static boolean
-ieee_read_type_index (info, pp, ptype)
- struct ieee_info *info;
- const bfd_byte **pp;
- debug_type *ptype;
-{
- const bfd_byte *start;
- bfd_vma indx;
-
- start = *pp;
-
- if (! ieee_read_number (info, pp, &indx))
- return false;
-
- if (indx < 256)
- {
- *ptype = ieee_builtin_type (info, start, indx);
- if (*ptype == NULL)
- return false;
- return true;
- }
-
- indx -= 256;
- if (! ieee_alloc_type (info, indx, true))
- return false;
-
- *ptype = info->types.types[indx].type;
-
- return true;
-}
-
-/* Parse IEEE debugging information for a file. This is passed the
- bytes which compose the Debug Information Part of an IEEE file. */
-
-boolean
-parse_ieee (dhandle, abfd, bytes, len)
- PTR dhandle;
- bfd *abfd;
- const bfd_byte *bytes;
- bfd_size_type len;
-{
- struct ieee_info info;
- unsigned int i;
- const bfd_byte *p, *pend;
-
- info.dhandle = dhandle;
- info.abfd = abfd;
- info.bytes = bytes;
- info.pend = bytes + len;
- info.blockstack.bsp = info.blockstack.stack;
- info.saw_filename = false;
- info.vars.alloc = 0;
- info.vars.vars = NULL;
- info.types.alloc = 0;
- info.types.types = NULL;
- info.tags = NULL;
- for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
- info.types.builtins[i] = DEBUG_TYPE_NULL;
-
- p = bytes;
- pend = info.pend;
- while (p < pend)
- {
- const bfd_byte *record_start;
- ieee_record_enum_type c;
-
- record_start = p;
-
- c = (ieee_record_enum_type) *p++;
-
- if (c == ieee_at_record_enum)
- c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
-
- if (c <= ieee_number_repeat_end_enum)
- {
- ieee_error (&info, record_start, "unexpected number");
- return false;
- }
-
- switch (c)
- {
- default:
- ieee_error (&info, record_start, "unexpected record type");
- return false;
-
- case ieee_bb_record_enum:
- if (! parse_ieee_bb (&info, &p))
- return false;
- break;
-
- case ieee_be_record_enum:
- if (! parse_ieee_be (&info, &p))
- return false;
- break;
-
- case ieee_nn_record:
- if (! parse_ieee_nn (&info, &p))
- return false;
- break;
-
- case ieee_ty_record_enum:
- if (! parse_ieee_ty (&info, &p))
- return false;
- break;
-
- case ieee_atn_record_enum:
- if (! parse_ieee_atn (&info, &p))
- return false;
- break;
- }
- }
-
- if (info.blockstack.bsp != info.blockstack.stack)
- {
- ieee_error (&info, (const bfd_byte *) NULL,
- "blocks left on stack at end");
- return false;
- }
-
- return true;
-}
-
-/* Handle an IEEE BB record. */
-
-static boolean
-parse_ieee_bb (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *block_start;
- bfd_byte b;
- bfd_vma size;
- const char *name;
- unsigned long namlen;
- char *namcopy = NULL;
- unsigned int fnindx;
- boolean skip;
-
- block_start = *pp;
-
- b = **pp;
- ++*pp;
-
- if (! ieee_read_number (info, pp, &size)
- || ! ieee_read_id (info, pp, &name, &namlen))
- return false;
-
- fnindx = (unsigned int) -1;
- skip = false;
-
- switch (b)
- {
- case 1:
- /* BB1: Type definitions local to a module. */
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_set_filename (info->dhandle, namcopy))
- return false;
- info->saw_filename = true;
-
- /* Discard any variables or types we may have seen before. */
- if (info->vars.vars != NULL)
- free (info->vars.vars);
- info->vars.vars = NULL;
- info->vars.alloc = 0;
- if (info->types.types != NULL)
- free (info->types.types);
- info->types.types = NULL;
- info->types.alloc = 0;
-
- /* Initialize the types to the global types. */
- if (info->global_types != NULL)
- {
- info->types.alloc = info->global_types->alloc;
- info->types.types = ((struct ieee_type *)
- xmalloc (info->types.alloc
- * sizeof (*info->types.types)));
- memcpy (info->types.types, info->global_types->types,
- info->types.alloc * sizeof (*info->types.types));
- }
-
- break;
-
- case 2:
- /* BB2: Global type definitions. The name is supposed to be
- empty, but we don't check. */
- if (! debug_set_filename (info->dhandle, "*global*"))
- return false;
- info->saw_filename = true;
- break;
-
- case 3:
- /* BB3: High level module block begin. We don't have to do
- anything here. The name is supposed to be the same as for
- the BB1, but we don't check. */
- break;
-
- case 4:
- /* BB4: Global function. */
- {
- bfd_vma stackspace, typindx, offset;
- debug_type return_type;
-
- if (! ieee_read_number (info, pp, &stackspace)
- || ! ieee_read_number (info, pp, &typindx)
- || ! ieee_read_expression (info, pp, &offset))
- return false;
-
- /* We have no way to record the stack space. FIXME. */
-
- if (typindx < 256)
- {
- return_type = ieee_builtin_type (info, block_start, typindx);
- if (return_type == DEBUG_TYPE_NULL)
- return false;
- }
- else
- {
- typindx -= 256;
- if (! ieee_alloc_type (info, typindx, true))
- return false;
- fnindx = typindx;
- return_type = info->types.types[typindx].type;
- if (debug_get_type_kind (info->dhandle, return_type)
- == DEBUG_KIND_FUNCTION)
- return_type = debug_get_return_type (info->dhandle,
- return_type);
- }
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_record_function (info->dhandle, namcopy, return_type,
- true, offset))
- return false;
- }
- break;
-
- case 5:
- /* BB5: File name for source line numbers. */
- {
- unsigned int i;
-
- /* We ignore the date and time. FIXME. */
- for (i = 0; i < 6; i++)
- {
- bfd_vma ignore;
- boolean present;
-
- if (! ieee_read_optional_number (info, pp, &ignore, &present))
- return false;
- if (! present)
- break;
- }
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_start_source (info->dhandle, namcopy))
- return false;
- }
- break;
-
- case 6:
- /* BB6: Local function or block. */
- {
- bfd_vma stackspace, typindx, offset;
-
- if (! ieee_read_number (info, pp, &stackspace)
- || ! ieee_read_number (info, pp, &typindx)
- || ! ieee_read_expression (info, pp, &offset))
- return false;
-
- /* We have no way to record the stack space. FIXME. */
-
- if (namlen == 0)
- {
- if (! debug_start_block (info->dhandle, offset))
- return false;
- /* Change b to indicate that this is a block
- rather than a function. */
- b = 0x86;
- }
- else
- {
- /* The MRI C++ compiler will output a fake function named
- __XRYCPP to hold C++ debugging information. We skip
- that function. This is not crucial, but it makes
- converting from IEEE to other debug formats work
- better. */
- if (strncmp (name, "__XRYCPP", namlen) == 0)
- skip = true;
- else
- {
- debug_type return_type;
-
- if (typindx < 256)
- {
- return_type = ieee_builtin_type (info, block_start,
- typindx);
- if (return_type == NULL)
- return false;
- }
- else
- {
- typindx -= 256;
- if (! ieee_alloc_type (info, typindx, true))
- return false;
- fnindx = typindx;
- return_type = info->types.types[typindx].type;
- if (debug_get_type_kind (info->dhandle, return_type)
- == DEBUG_KIND_FUNCTION)
- return_type = debug_get_return_type (info->dhandle,
- return_type);
- }
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_record_function (info->dhandle, namcopy,
- return_type, false, offset))
- return false;
- }
- }
- }
- break;
-
- case 10:
- /* BB10: Assembler module scope. In the normal case, we
- completely ignore all this information. FIXME. */
- {
- const char *inam, *vstr;
- unsigned long inamlen, vstrlen;
- bfd_vma tool_type;
- boolean present;
- unsigned int i;
-
- if (! info->saw_filename)
- {
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_set_filename (info->dhandle, namcopy))
- return false;
- info->saw_filename = true;
- }
-
- if (! ieee_read_id (info, pp, &inam, &inamlen)
- || ! ieee_read_number (info, pp, &tool_type)
- || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
- return false;
- for (i = 0; i < 6; i++)
- {
- bfd_vma ignore;
-
- if (! ieee_read_optional_number (info, pp, &ignore, &present))
- return false;
- if (! present)
- break;
- }
- }
- break;
-
- case 11:
- /* BB11: Module section. We completely ignore all this
- information. FIXME. */
- {
- bfd_vma sectype, secindx, offset, map;
- boolean present;
-
- if (! ieee_read_number (info, pp, &sectype)
- || ! ieee_read_number (info, pp, &secindx)
- || ! ieee_read_expression (info, pp, &offset)
- || ! ieee_read_optional_number (info, pp, &map, &present))
- return false;
- }
- break;
-
- default:
- ieee_error (info, block_start, "unknown BB type");
- return false;
- }
-
-
- /* Push this block on the block stack. */
-
- if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
- {
- ieee_error (info, (const bfd_byte *) NULL, "stack overflow");
- return false;
- }
-
- info->blockstack.bsp->kind = b;
- if (b == 5)
- info->blockstack.bsp->filename = namcopy;
- info->blockstack.bsp->fnindx = fnindx;
- info->blockstack.bsp->skip = skip;
- ++info->blockstack.bsp;
-
- return true;
-}
-
-/* Handle an IEEE BE record. */
-
-static boolean
-parse_ieee_be (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- bfd_vma offset;
-
- if (info->blockstack.bsp <= info->blockstack.stack)
- {
- ieee_error (info, *pp, "stack underflow");
- return false;
- }
- --info->blockstack.bsp;
-
- switch (info->blockstack.bsp->kind)
- {
- case 2:
- /* When we end the global typedefs block, we copy out the the
- contents of info->vars. This is because the variable indices
- may be reused in the local blocks. However, we need to
- preserve them so that we can locate a function returning a
- reference variable whose type is named in the global typedef
- block. */
- info->global_vars = ((struct ieee_vars *)
- xmalloc (sizeof *info->global_vars));
- info->global_vars->alloc = info->vars.alloc;
- info->global_vars->vars = ((struct ieee_var *)
- xmalloc (info->vars.alloc
- * sizeof (*info->vars.vars)));
- memcpy (info->global_vars->vars, info->vars.vars,
- info->vars.alloc * sizeof (*info->vars.vars));
-
- /* We also copy out the non builtin parts of info->types, since
- the types are discarded when we start a new block. */
- info->global_types = ((struct ieee_types *)
- xmalloc (sizeof *info->global_types));
- info->global_types->alloc = info->types.alloc;
- info->global_types->types = ((struct ieee_type *)
- xmalloc (info->types.alloc
- * sizeof (*info->types.types)));
- memcpy (info->global_types->types, info->types.types,
- info->types.alloc * sizeof (*info->types.types));
- memset (info->global_types->builtins, 0,
- sizeof (info->global_types->builtins));
-
- break;
-
- case 4:
- case 6:
- if (! ieee_read_expression (info, pp, &offset))
- return false;
- if (! info->blockstack.bsp->skip)
- {
- if (! debug_end_function (info->dhandle, offset + 1))
- return false;
- }
- break;
-
- case 0x86:
- /* This is BE6 when BB6 started a block rather than a local
- function. */
- if (! ieee_read_expression (info, pp, &offset))
- return false;
- if (! debug_end_block (info->dhandle, offset + 1))
- return false;
- break;
-
- case 5:
- /* When we end a BB5, we look up the stack for the last BB5, if
- there is one, so that we can call debug_start_source. */
- if (info->blockstack.bsp > info->blockstack.stack)
- {
- struct ieee_block *bl;
-
- bl = info->blockstack.bsp;
- do
- {
- --bl;
- if (bl->kind == 5)
- {
- if (! debug_start_source (info->dhandle, bl->filename))
- return false;
- break;
- }
- }
- while (bl != info->blockstack.stack);
- }
- break;
-
- case 11:
- if (! ieee_read_expression (info, pp, &offset))
- return false;
- /* We just ignore the module size. FIXME. */
- break;
-
- default:
- /* Other block types do not have any trailing information. */
- break;
- }
-
- return true;
-}
-
-/* Parse an NN record. */
-
-static boolean
-parse_ieee_nn (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *nn_start;
- bfd_vma varindx;
- const char *name;
- unsigned long namlen;
-
- nn_start = *pp;
-
- if (! ieee_read_number (info, pp, &varindx)
- || ! ieee_read_id (info, pp, &name, &namlen))
- return false;
-
- if (varindx < 32)
- {
- ieee_error (info, nn_start, "illegal variable index");
- return false;
- }
- varindx -= 32;
-
- if (varindx >= info->vars.alloc)
- {
- unsigned int alloc;
-
- alloc = info->vars.alloc;
- if (alloc == 0)
- alloc = 4;
- while (varindx >= alloc)
- alloc *= 2;
- info->vars.vars = ((struct ieee_var *)
- xrealloc (info->vars.vars,
- alloc * sizeof *info->vars.vars));
- memset (info->vars.vars + info->vars.alloc, 0,
- (alloc - info->vars.alloc) * sizeof *info->vars.vars);
- info->vars.alloc = alloc;
- }
-
- info->vars.vars[varindx].name = name;
- info->vars.vars[varindx].namlen = namlen;
-
- return true;
-}
-
-/* Parse a TY record. */
-
-static boolean
-parse_ieee_ty (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
- bfd_vma typeindx, varindx, tc;
- PTR dhandle;
- boolean tag, typdef;
- debug_type *arg_slots;
- unsigned long type_bitsize;
- debug_type type;
-
- ty_start = *pp;
-
- if (! ieee_read_number (info, pp, &typeindx))
- return false;
-
- if (typeindx < 256)
- {
- ieee_error (info, ty_start, "illegal type index");
- return false;
- }
-
- typeindx -= 256;
- if (! ieee_alloc_type (info, typeindx, false))
- return false;
-
- if (**pp != 0xce)
- {
- ieee_error (info, *pp, "unknown TY code");
- return false;
- }
- ++*pp;
-
- ty_var_start = *pp;
-
- if (! ieee_read_number (info, pp, &varindx))
- return false;
-
- if (varindx < 32)
- {
- ieee_error (info, ty_var_start, "illegal variable index");
- return false;
- }
- varindx -= 32;
-
- if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
- {
- ieee_error (info, ty_var_start, "undefined variable in TY");
- return false;
- }
-
- ty_code_start = *pp;
-
- if (! ieee_read_number (info, pp, &tc))
- return false;
-
- dhandle = info->dhandle;
-
- tag = false;
- typdef = false;
- arg_slots = NULL;
- type_bitsize = 0;
- switch (tc)
- {
- default:
- ieee_error (info, ty_code_start, "unknown TY code");
- return false;
-
- case '!':
- /* Unknown type, with size. We treat it as int. FIXME. */
- {
- bfd_vma size;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
- type = debug_make_int_type (dhandle, size, false);
- }
- break;
-
- case 'A': /* Array. */
- case 'a': /* FORTRAN array in column/row order. FIXME: Not
- distinguished from normal array. */
- {
- debug_type ele_type;
- bfd_vma lower, upper;
-
- if (! ieee_read_type_index (info, pp, &ele_type)
- || ! ieee_read_number (info, pp, &lower)
- || ! ieee_read_number (info, pp, &upper))
- return false;
- type = debug_make_array_type (dhandle, ele_type,
- ieee_builtin_type (info, ty_code_start,
- ((unsigned int)
- builtin_int)),
- (bfd_signed_vma) lower,
- (bfd_signed_vma) upper,
- false);
- }
- break;
-
- case 'E':
- /* Simple enumeration. */
- {
- bfd_vma size;
- unsigned int alloc;
- const char **names;
- unsigned int c;
- bfd_signed_vma *vals;
- unsigned int i;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
- /* FIXME: we ignore the enumeration size. */
-
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- memset (names, 0, alloc * sizeof *names);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc (names, alloc * sizeof *names));
- }
-
- names[c] = savestring (name, namlen);
- if (names[c] == NULL)
- return false;
- ++c;
- }
-
- names[c] = NULL;
-
- vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
- for (i = 0; i < c; i++)
- vals[i] = i;
-
- type = debug_make_enum_type (dhandle, names, vals);
- tag = true;
- }
- break;
-
- case 'G':
- /* Struct with bit fields. */
- {
- bfd_vma size;
- unsigned int alloc;
- debug_field *fields;
- unsigned int c;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
-
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
- debug_type ftype;
- bfd_vma bitpos, bitsize;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
- if (! ieee_read_type_index (info, pp, &ftype)
- || ! ieee_read_number (info, pp, &bitpos)
- || ! ieee_read_number (info, pp, &bitsize))
- return false;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, alloc * sizeof *fields));
- }
-
- fields[c] = debug_make_field (dhandle, savestring (name, namlen),
- ftype, bitpos, bitsize,
- DEBUG_VISIBILITY_PUBLIC);
- if (fields[c] == NULL)
- return false;
- ++c;
- }
-
- fields[c] = NULL;
-
- type = debug_make_struct_type (dhandle, true, size, fields);
- tag = true;
- }
- break;
-
- case 'N':
- /* Enumeration. */
- {
- unsigned int alloc;
- const char **names;
- bfd_signed_vma *vals;
- unsigned int c;
-
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
- bfd_vma val;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
- if (! ieee_read_number (info, pp, &val))
- return false;
-
- /* If the length of the name is zero, then the value is
- actually the size of the enum. We ignore this
- information. FIXME. */
- if (namlen == 0)
- continue;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc (names, alloc * sizeof *names));
- vals = ((bfd_signed_vma *)
- xrealloc (vals, alloc * sizeof *vals));
- }
-
- names[c] = savestring (name, namlen);
- if (names[c] == NULL)
- return false;
- vals[c] = (bfd_signed_vma) val;
- ++c;
- }
-
- names[c] = NULL;
-
- type = debug_make_enum_type (dhandle, names, vals);
- tag = true;
- }
- break;
-
- case 'O': /* Small pointer. We don't distinguish small and large
- pointers. FIXME. */
- case 'P': /* Large pointer. */
- {
- debug_type t;
-
- if (! ieee_read_type_index (info, pp, &t))
- return false;
- type = debug_make_pointer_type (dhandle, t);
- }
- break;
-
- case 'R':
- /* Range. */
- {
- bfd_vma low, high, signedp, size;
-
- if (! ieee_read_number (info, pp, &low)
- || ! ieee_read_number (info, pp, &high)
- || ! ieee_read_number (info, pp, &signedp)
- || ! ieee_read_number (info, pp, &size))
- return false;
-
- type = debug_make_range_type (dhandle,
- debug_make_int_type (dhandle, size,
- ! signedp),
- (bfd_signed_vma) low,
- (bfd_signed_vma) high);
- }
- break;
-
- case 'S': /* Struct. */
- case 'U': /* Union. */
- {
- bfd_vma size;
- unsigned int alloc;
- debug_field *fields;
- unsigned int c;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
-
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
- bfd_vma tindx;
- bfd_vma offset;
- debug_type ftype;
- bfd_vma bitsize;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
- if (! ieee_read_number (info, pp, &tindx)
- || ! ieee_read_number (info, pp, &offset))
- return false;
-
- if (tindx < 256)
- {
- ftype = ieee_builtin_type (info, ty_code_start, tindx);
- bitsize = 0;
- offset *= 8;
- }
- else
- {
- struct ieee_type *t;
-
- tindx -= 256;
- if (! ieee_alloc_type (info, tindx, true))
- return false;
- t = info->types.types + tindx;
- ftype = t->type;
- bitsize = t->bitsize;
- if (bitsize == 0)
- offset *= 8;
- }
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, alloc * sizeof *fields));
- }
-
- fields[c] = debug_make_field (dhandle, savestring (name, namlen),
- ftype, offset, bitsize,
- DEBUG_VISIBILITY_PUBLIC);
- if (fields[c] == NULL)
- return false;
- ++c;
- }
-
- fields[c] = NULL;
-
- type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
- tag = true;
- }
- break;
-
- case 'T':
- /* Typedef. */
- if (! ieee_read_type_index (info, pp, &type))
- return false;
- typdef = true;
- break;
-
- case 'X':
- /* Procedure. FIXME: This is an extern declaration, which we
- have no way of representing. */
- {
- bfd_vma attr;
- debug_type rtype;
- bfd_vma nargs;
- boolean present;
- struct ieee_var *pv;
-
- /* FIXME: We ignore the attribute and the argument names. */
-
- if (! ieee_read_number (info, pp, &attr)
- || ! ieee_read_type_index (info, pp, &rtype)
- || ! ieee_read_number (info, pp, &nargs))
- return false;
- do
- {
- const char *name;
- unsigned long namlen;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- }
- while (present);
-
- pv = info->vars.vars + varindx;
- pv->kind = IEEE_EXTERNAL;
- if (pv->namlen > 0
- && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
- {
- /* Set up the return type as an indirect type pointing to
- the variable slot, so that we can change it to a
- reference later if appropriate. */
- pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
- *pv->pslot = rtype;
- rtype = debug_make_indirect_type (dhandle, pv->pslot,
- (const char *) NULL);
- }
-
- type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
- false);
- }
- break;
-
- case 'V':
- /* Void. This is not documented, but the MRI compiler emits it. */
- type = debug_make_void_type (dhandle);
- break;
-
- case 'Z':
- /* Array with 0 lower bound. */
- {
- debug_type etype;
- bfd_vma high;
-
- if (! ieee_read_type_index (info, pp, &etype)
- || ! ieee_read_number (info, pp, &high))
- return false;
-
- type = debug_make_array_type (dhandle, etype,
- ieee_builtin_type (info, ty_code_start,
- ((unsigned int)
- builtin_int)),
- 0, (bfd_signed_vma) high, false);
- }
- break;
-
- case 'c': /* Complex. */
- case 'd': /* Double complex. */
- {
- const char *name;
- unsigned long namlen;
-
- /* FIXME: I don't know what the name means. */
-
- if (! ieee_read_id (info, pp, &name, &namlen))
- return false;
-
- type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
- }
- break;
-
- case 'f':
- /* Pascal file name. FIXME. */
- ieee_error (info, ty_code_start, "Pascal file name not supported");
- return false;
-
- case 'g':
- /* Bitfield type. */
- {
- bfd_vma signedp, bitsize, dummy;
- const bfd_byte *hold;
- boolean present;
-
- if (! ieee_read_number (info, pp, &signedp)
- || ! ieee_read_number (info, pp, &bitsize))
- return false;
-
- /* I think the documentation says that there is a type index,
- but some actual files do not have one. */
- hold = *pp;
- if (! ieee_read_optional_number (info, pp, &dummy, &present))
- return false;
- if (! present)
- {
- /* FIXME: This is just a guess. */
- type = debug_make_int_type (dhandle, 4,
- signedp ? false : true);
- }
- else
- {
- *pp = hold;
- if (! ieee_read_type_index (info, pp, &type))
- return false;
- }
- type_bitsize = bitsize;
- }
- break;
-
- case 'n':
- /* Qualifier. */
- {
- bfd_vma kind;
- debug_type t;
-
- if (! ieee_read_number (info, pp, &kind)
- || ! ieee_read_type_index (info, pp, &t))
- return false;
-
- switch (kind)
- {
- default:
- ieee_error (info, ty_start, "unsupported qualifer");
- return false;
-
- case 1:
- type = debug_make_const_type (dhandle, t);
- break;
-
- case 2:
- type = debug_make_volatile_type (dhandle, t);
- break;
- }
- }
- break;
-
- case 's':
- /* Set. */
- {
- bfd_vma size;
- debug_type etype;
-
- if (! ieee_read_number (info, pp, &size)
- || ! ieee_read_type_index (info, pp, &etype))
- return false;
-
- /* FIXME: We ignore the size. */
-
- type = debug_make_set_type (dhandle, etype, false);
- }
- break;
-
- case 'x':
- /* Procedure with compiler dependencies. */
- {
- struct ieee_var *pv;
- bfd_vma attr, frame_type, push_mask, nargs, level, father;
- debug_type rtype;
- debug_type *arg_types;
- boolean varargs;
- boolean present;
-
- /* FIXME: We ignore some of this information. */
-
- pv = info->vars.vars + varindx;
-
- if (! ieee_read_number (info, pp, &attr)
- || ! ieee_read_number (info, pp, &frame_type)
- || ! ieee_read_number (info, pp, &push_mask)
- || ! ieee_read_type_index (info, pp, &rtype)
- || ! ieee_read_number (info, pp, &nargs))
- return false;
- if (nargs == (bfd_vma) -1)
- {
- arg_types = NULL;
- varargs = false;
- }
- else
- {
- unsigned int i;
-
- arg_types = ((debug_type *)
- xmalloc ((nargs + 1) * sizeof *arg_types));
- for (i = 0; i < nargs; i++)
- if (! ieee_read_type_index (info, pp, arg_types + i))
- return false;
-
- /* If the last type is pointer to void, this is really a
- varargs function. */
- varargs = false;
- if (nargs > 0)
- {
- debug_type last;
-
- last = arg_types[nargs - 1];
- if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
- && (debug_get_type_kind (dhandle,
- debug_get_target_type (dhandle,
- last))
- == DEBUG_KIND_VOID))
- {
- --nargs;
- varargs = true;
- }
- }
-
- /* If there are any pointer arguments, turn them into
- indirect types in case we later need to convert them to
- reference types. */
- for (i = 0; i < nargs; i++)
- {
- if (debug_get_type_kind (dhandle, arg_types[i])
- == DEBUG_KIND_POINTER)
- {
- if (arg_slots == NULL)
- {
- arg_slots = ((debug_type *)
- xmalloc (nargs * sizeof *arg_slots));
- memset (arg_slots, 0, nargs * sizeof *arg_slots);
- }
- arg_slots[i] = arg_types[i];
- arg_types[i] =
- debug_make_indirect_type (dhandle,
- arg_slots + i,
- (const char *) NULL);
- }
- }
-
- arg_types[nargs] = DEBUG_TYPE_NULL;
- }
- if (! ieee_read_number (info, pp, &level)
- || ! ieee_read_optional_number (info, pp, &father, &present))
- return false;
-
- /* We can't distinguish between a global function and a static
- function. */
- pv->kind = IEEE_FUNCTION;
-
- if (pv->namlen > 0
- && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
- {
- /* Set up the return type as an indirect type pointing to
- the variable slot, so that we can change it to a
- reference later if appropriate. */
- pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
- *pv->pslot = rtype;
- rtype = debug_make_indirect_type (dhandle, pv->pslot,
- (const char *) NULL);
- }
-
- type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
- }
- break;
- }
-
- /* Record the type in the table. */
-
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- info->vars.vars[varindx].type = type;
-
- if ((tag || typdef)
- && info->vars.vars[varindx].namlen > 0)
- {
- const char *name;
-
- name = savestring (info->vars.vars[varindx].name,
- info->vars.vars[varindx].namlen);
- if (typdef)
- type = debug_name_type (dhandle, name, type);
- else if (tc == 'E' || tc == 'N')
- type = debug_tag_type (dhandle, name, type);
- else
- {
- struct ieee_tag *it;
-
- /* We must allocate all struct tags as indirect types, so
- that if we later see a definition of the tag as a C++
- record we can update the indirect slot and automatically
- change all the existing references. */
- it = (struct ieee_tag *) xmalloc (sizeof *it);
- memset (it, 0, sizeof *it);
- it->next = info->tags;
- info->tags = it;
- it->name = name;
- it->slot = type;
-
- type = debug_make_indirect_type (dhandle, &it->slot, name);
- type = debug_tag_type (dhandle, name, type);
-
- it->type = type;
- }
- if (type == NULL)
- return false;
- }
-
- info->types.types[typeindx].type = type;
- info->types.types[typeindx].arg_slots = arg_slots;
- info->types.types[typeindx].bitsize = type_bitsize;
-
- /* We may have already allocated type as an indirect type pointing
- to slot. It does no harm to replace the indirect type with the
- real type. Filling in slot as well handles the indirect types
- which are already hanging around. */
- if (info->types.types[typeindx].pslot != NULL)
- *info->types.types[typeindx].pslot = type;
-
- return true;
-}
-
-/* Parse an ATN record. */
-
-static boolean
-parse_ieee_atn (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *atn_start, *atn_code_start;
- bfd_vma varindx;
- struct ieee_var *pvar;
- debug_type type;
- bfd_vma atn_code;
- PTR dhandle;
- bfd_vma v, v2, v3, v4, v5;
- const char *name;
- unsigned long namlen;
- char *namcopy;
- boolean present;
- int blocktype;
-
- atn_start = *pp;
-
- if (! ieee_read_number (info, pp, &varindx)
- || ! ieee_read_type_index (info, pp, &type))
- return false;
-
- atn_code_start = *pp;
-
- if (! ieee_read_number (info, pp, &atn_code))
- return false;
-
- if (varindx == 0)
- {
- pvar = NULL;
- name = "";
- namlen = 0;
- }
- else if (varindx < 32)
- {
- ieee_error (info, atn_start, "illegal variable index");
- return false;
- }
- else
- {
- varindx -= 32;
- if (varindx >= info->vars.alloc
- || info->vars.vars[varindx].name == NULL)
- {
- /* The MRI compiler or linker sometimes omits the NN record
- for a pmisc record. */
- if (atn_code == 62)
- {
- if (varindx >= info->vars.alloc)
- {
- unsigned int alloc;
-
- alloc = info->vars.alloc;
- if (alloc == 0)
- alloc = 4;
- while (varindx >= alloc)
- alloc *= 2;
- info->vars.vars = ((struct ieee_var *)
- xrealloc (info->vars.vars,
- (alloc
- * sizeof *info->vars.vars)));
- memset (info->vars.vars + info->vars.alloc, 0,
- ((alloc - info->vars.alloc)
- * sizeof *info->vars.vars));
- info->vars.alloc = alloc;
- }
-
- pvar = info->vars.vars + varindx;
- pvar->name = "";
- pvar->namlen = 0;
- }
- else
- {
- ieee_error (info, atn_start, "undefined variable in ATN");
- return false;
- }
- }
-
- pvar = info->vars.vars + varindx;
-
- pvar->type = type;
-
- name = pvar->name;
- namlen = pvar->namlen;
- }
-
- dhandle = info->dhandle;
-
- /* If we are going to call debug_record_variable with a pointer
- type, change the type to an indirect type so that we can later
- change it to a reference type if we encounter a C++ pmisc 'R'
- record. */
- if (pvar != NULL
- && type != DEBUG_TYPE_NULL
- && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER)
- {
- switch (atn_code)
- {
- case 1:
- case 2:
- case 3:
- case 5:
- case 8:
- case 10:
- pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot);
- *pvar->pslot = type;
- type = debug_make_indirect_type (dhandle, pvar->pslot,
- (const char *) NULL);
- pvar->type = type;
- break;
- }
- }
-
- switch (atn_code)
- {
- default:
- ieee_error (info, atn_code_start, "unknown ATN type");
- return false;
-
- case 1:
- /* Automatic variable. */
- if (! ieee_read_number (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_LOCAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
-
- case 2:
- /* Register variable. */
- if (! ieee_read_number (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_LOCAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
- ieee_regno_to_genreg (info->abfd, v));
-
- case 3:
- /* Static variable. */
- if (! ieee_require_asn (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (info->blockstack.bsp <= info->blockstack.stack)
- blocktype = 0;
- else
- blocktype = info->blockstack.bsp[-1].kind;
- if (pvar != NULL)
- {
- if (blocktype == 4 || blocktype == 6)
- pvar->kind = IEEE_LOCAL;
- else
- pvar->kind = IEEE_STATIC;
- }
- return debug_record_variable (dhandle, namcopy, type,
- (blocktype == 4 || blocktype == 6
- ? DEBUG_LOCAL_STATIC
- : DEBUG_STATIC),
- v);
-
- case 4:
- /* External function. We don't currently record these. FIXME. */
- if (pvar != NULL)
- pvar->kind = IEEE_EXTERNAL;
- return true;
-
- case 5:
- /* External variable. We don't currently record these. FIXME. */
- if (pvar != NULL)
- pvar->kind = IEEE_EXTERNAL;
- return true;
-
- case 7:
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2)
- || ! ieee_read_optional_number (info, pp, &v3, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v4, &present))
- return false;
- }
-
- /* We just ignore the two optional fields in v3 and v4, since
- they are not defined. */
-
- if (! ieee_require_asn (info, pp, &v3))
- return false;
-
- /* We have no way to record the column number. FIXME. */
-
- return debug_record_line (dhandle, v, v3);
-
- case 8:
- /* Global variable. */
- if (! ieee_require_asn (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_GLOBAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
-
- case 9:
- /* Variable lifetime information. */
- if (! ieee_read_number (info, pp, &v))
- return false;
-
- /* We have no way to record this information. FIXME. */
- return true;
-
- case 10:
- /* Locked register. The spec says that there are two required
- fields, but at least on occasion the MRI compiler only emits
- one. */
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_optional_number (info, pp, &v2, &present))
- return false;
-
- /* I think this means a variable that is both in a register and
- a frame slot. We ignore the frame slot. FIXME. */
-
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_LOCAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v);
-
- case 11:
- /* Reserved for FORTRAN common. */
- ieee_error (info, atn_code_start, "unsupported ATN11");
-
- /* Return true to keep going. */
- return true;
-
- case 12:
- /* Based variable. */
- v3 = 0;
- v4 = 0x80;
- v5 = 0;
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2)
- || ! ieee_read_optional_number (info, pp, &v3, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v4, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v5, &present))
- return false;
- }
- }
-
- /* We have no way to record this information. FIXME. */
-
- ieee_error (info, atn_code_start, "unsupported ATN12");
-
- /* Return true to keep going. */
- return true;
-
- case 16:
- /* Constant. The description of this that I have is ambiguous,
- so I'm not going to try to implement it. */
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_optional_number (info, pp, &v2, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v2, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- }
- }
-
- if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum)
- {
- if (! ieee_require_asn (info, pp, &v3))
- return false;
- }
-
- return true;
-
- case 19:
- /* Static variable from assembler. */
- v2 = 0;
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_optional_number (info, pp, &v2, &present)
- || ! ieee_require_asn (info, pp, &v3))
- return false;
- namcopy = savestring (name, namlen);
- /* We don't really handle this correctly. FIXME. */
- return debug_record_variable (dhandle, namcopy,
- debug_make_void_type (dhandle),
- v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC,
- v3);
-
- case 62:
- /* Procedure miscellaneous information. */
- case 63:
- /* Variable miscellaneous information. */
- case 64:
- /* Module miscellaneous information. */
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2)
- || ! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
-
- if (atn_code == 62 && v == 80)
- {
- if (present)
- {
- ieee_error (info, atn_code_start,
- "unexpected string in C++ misc");
- return false;
- }
- return ieee_read_cxx_misc (info, pp, v2);
- }
-
- /* We just ignore all of this stuff. FIXME. */
-
- for (; v2 > 0; --v2)
- {
- switch ((ieee_record_enum_type) **pp)
- {
- default:
- ieee_error (info, *pp, "bad misc record");
- return false;
-
- case ieee_at_record_enum:
- if (! ieee_require_atn65 (info, pp, &name, &namlen))
- return false;
- break;
-
- case ieee_e2_first_byte_enum:
- if (! ieee_require_asn (info, pp, &v3))
- return false;
- break;
- }
- }
-
- return true;
- }
-
- /*NOTREACHED*/
-}
-
-/* Handle C++ debugging miscellaneous records. This is called for
- procedure miscellaneous records of type 80. */
-
-static boolean
-ieee_read_cxx_misc (info, pp, count)
- struct ieee_info *info;
- const bfd_byte **pp;
- unsigned long count;
-{
- const bfd_byte *start;
- bfd_vma category;
-
- start = *pp;
-
- /* Get the category of C++ misc record. */
- if (! ieee_require_asn (info, pp, &category))
- return false;
- --count;
-
- switch (category)
- {
- default:
- ieee_error (info, start, "unrecognized C++ misc record");
- return false;
-
- case 'T':
- if (! ieee_read_cxx_class (info, pp, count))
- return false;
- break;
-
- case 'M':
- {
- bfd_vma flags;
- const char *name;
- unsigned long namlen;
-
- /* The IEEE spec indicates that the 'M' record only has a
- flags field. The MRI compiler also emits the name of the
- function. */
-
- if (! ieee_require_asn (info, pp, &flags))
- return false;
- if (*pp < info->pend
- && (ieee_record_enum_type) **pp == ieee_at_record_enum)
- {
- if (! ieee_require_atn65 (info, pp, &name, &namlen))
- return false;
- }
-
- /* This is emitted for method functions, but I don't think we
- care very much. It might help if it told us useful
- information like the class with which this function is
- associated, but it doesn't, so it isn't helpful. */
- }
- break;
-
- case 'B':
- if (! ieee_read_cxx_defaults (info, pp, count))
- return false;
- break;
-
- case 'z':
- {
- const char *name, *mangled, *class;
- unsigned long namlen, mangledlen, classlen;
- bfd_vma control;
-
- /* Pointer to member. */
-
- if (! ieee_require_atn65 (info, pp, &name, &namlen)
- || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)
- || ! ieee_require_atn65 (info, pp, &class, &classlen)
- || ! ieee_require_asn (info, pp, &control))
- return false;
-
- /* FIXME: We should now track down name and change its type. */
- }
- break;
-
- case 'R':
- if (! ieee_read_reference (info, pp))
- return false;
- break;
- }
-
- return true;
-}
-
-/* Read a C++ class definition. This is a pmisc type 80 record of
- category 'T'. */
-
-static boolean
-ieee_read_cxx_class (info, pp, count)
- struct ieee_info *info;
- const bfd_byte **pp;
- unsigned long count;
-{
- const bfd_byte *start;
- bfd_vma class;
- const char *tag;
- unsigned long taglen;
- struct ieee_tag *it;
- PTR dhandle;
- debug_field *fields;
- unsigned int field_count, field_alloc;
- debug_baseclass *baseclasses;
- unsigned int baseclasses_count, baseclasses_alloc;
- const debug_field *structfields;
- struct ieee_method
- {
- const char *name;
- unsigned long namlen;
- debug_method_variant *variants;
- unsigned count;
- unsigned int alloc;
- } *methods;
- unsigned int methods_count, methods_alloc;
- debug_type vptrbase;
- boolean ownvptr;
- debug_method *dmethods;
-
- start = *pp;
-
- if (! ieee_require_asn (info, pp, &class))
- return false;
- --count;
-
- if (! ieee_require_atn65 (info, pp, &tag, &taglen))
- return false;
- --count;
-
- /* Find the C struct with this name. */
- for (it = info->tags; it != NULL; it = it->next)
- if (it->name[0] == tag[0]
- && strncmp (it->name, tag, taglen) == 0
- && strlen (it->name) == taglen)
- break;
- if (it == NULL)
- {
- ieee_error (info, start, "undefined C++ object");
- return false;
- }
-
- dhandle = info->dhandle;
-
- fields = NULL;
- field_count = 0;
- field_alloc = 0;
- baseclasses = NULL;
- baseclasses_count = 0;
- baseclasses_alloc = 0;
- methods = NULL;
- methods_count = 0;
- methods_alloc = 0;
- vptrbase = DEBUG_TYPE_NULL;
- ownvptr = false;
-
- structfields = debug_get_fields (dhandle, it->type);
-
- while (count > 0)
- {
- bfd_vma id;
- const bfd_byte *spec_start;
-
- spec_start = *pp;
-
- if (! ieee_require_asn (info, pp, &id))
- return false;
- --count;
-
- switch (id)
- {
- default:
- ieee_error (info, spec_start, "unrecognized C++ object spec");
- return false;
-
- case 'b':
- {
- bfd_vma flags, cinline;
- const char *basename, *fieldname;
- unsigned long baselen, fieldlen;
- char *basecopy;
- debug_type basetype;
- bfd_vma bitpos;
- boolean virtualp;
- enum debug_visibility visibility;
- debug_baseclass baseclass;
-
- /* This represents a base or friend class. */
-
- if (! ieee_require_asn (info, pp, &flags)
- || ! ieee_require_atn65 (info, pp, &basename, &baselen)
- || ! ieee_require_asn (info, pp, &cinline)
- || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))
- return false;
- count -= 4;
-
- /* We have no way of recording friend information, so we
- just ignore it. */
- if ((flags & BASEFLAGS_FRIEND) != 0)
- break;
-
- /* I assume that either all of the members of the
- baseclass are included in the object, starting at the
- beginning of the object, or that none of them are
- included. */
-
- if ((fieldlen == 0) == (cinline == 0))
- {
- ieee_error (info, start, "unsupported C++ object type");
- return false;
- }
-
- basecopy = savestring (basename, baselen);
- basetype = debug_find_tagged_type (dhandle, basecopy,
- DEBUG_KIND_ILLEGAL);
- free (basecopy);
- if (basetype == DEBUG_TYPE_NULL)
- {
- ieee_error (info, start, "C++ base class not defined");
- return false;
- }
-
- if (fieldlen == 0)
- bitpos = 0;
- else
- {
- const debug_field *pf;
-
- if (structfields == NULL)
- {
- ieee_error (info, start, "C++ object has no fields");
- return false;
- }
-
- for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)
- {
- const char *fname;
-
- fname = debug_get_field_name (dhandle, *pf);
- if (fname == NULL)
- return false;
- if (fname[0] == fieldname[0]
- && strncmp (fname, fieldname, fieldlen) == 0
- && strlen (fname) == fieldlen)
- break;
- }
- if (*pf == DEBUG_FIELD_NULL)
- {
- ieee_error (info, start,
- "C++ base class not found in container");
- return false;
- }
-
- bitpos = debug_get_field_bitpos (dhandle, *pf);
- }
-
- if ((flags & BASEFLAGS_VIRTUAL) != 0)
- virtualp = true;
- else
- virtualp = false;
- if ((flags & BASEFLAGS_PRIVATE) != 0)
- visibility = DEBUG_VISIBILITY_PRIVATE;
- else
- visibility = DEBUG_VISIBILITY_PUBLIC;
-
- baseclass = debug_make_baseclass (dhandle, basetype, bitpos,
- virtualp, visibility);
- if (baseclass == DEBUG_BASECLASS_NULL)
- return false;
-
- if (baseclasses_count + 1 >= baseclasses_alloc)
- {
- baseclasses_alloc += 10;
- baseclasses = ((debug_baseclass *)
- xrealloc (baseclasses,
- (baseclasses_alloc
- * sizeof *baseclasses)));
- }
-
- baseclasses[baseclasses_count] = baseclass;
- ++baseclasses_count;
- baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;
- }
- break;
-
- case 'd':
- {
- bfd_vma flags;
- const char *fieldname, *mangledname;
- unsigned long fieldlen, mangledlen;
- char *fieldcopy;
- boolean staticp;
- debug_type ftype;
- const debug_field *pf = NULL;
- enum debug_visibility visibility;
- debug_field field;
-
- /* This represents a data member. */
-
- if (! ieee_require_asn (info, pp, &flags)
- || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)
- || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))
- return false;
- count -= 3;
-
- fieldcopy = savestring (fieldname, fieldlen);
-
- staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false;
-
- if (staticp)
- {
- struct ieee_var *pv, *pvend;
-
- /* See if we can find a definition for this variable. */
- pv = info->vars.vars;
- pvend = pv + info->vars.alloc;
- for (; pv < pvend; pv++)
- if (pv->namlen == mangledlen
- && strncmp (pv->name, mangledname, mangledlen) == 0)
- break;
- if (pv < pvend)
- ftype = pv->type;
- else
- {
- /* This can happen if the variable is never used. */
- ftype = ieee_builtin_type (info, start,
- (unsigned int) builtin_void);
- }
- }
- else
- {
- unsigned int findx;
-
- if (structfields == NULL)
- {
- ieee_error (info, start, "C++ object has no fields");
- return false;
- }
-
- for (pf = structfields, findx = 0;
- *pf != DEBUG_FIELD_NULL;
- pf++, findx++)
- {
- const char *fname;
-
- fname = debug_get_field_name (dhandle, *pf);
- if (fname == NULL)
- return false;
- if (fname[0] == mangledname[0]
- && strncmp (fname, mangledname, mangledlen) == 0
- && strlen (fname) == mangledlen)
- break;
- }
- if (*pf == DEBUG_FIELD_NULL)
- {
- ieee_error (info, start,
- "C++ data member not found in container");
- return false;
- }
-
- ftype = debug_get_field_type (dhandle, *pf);
-
- if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)
- {
- /* We might need to convert this field into a
- reference type later on, so make it an indirect
- type. */
- if (it->fslots == NULL)
- {
- unsigned int fcnt;
- const debug_field *pfcnt;
-
- fcnt = 0;
- for (pfcnt = structfields;
- *pfcnt != DEBUG_FIELD_NULL;
- pfcnt++)
- ++fcnt;
- it->fslots = ((debug_type *)
- xmalloc (fcnt * sizeof *it->fslots));
- memset (it->fslots, 0,
- fcnt * sizeof *it->fslots);
- }
-
- if (ftype == DEBUG_TYPE_NULL)
- return false;
- it->fslots[findx] = ftype;
- ftype = debug_make_indirect_type (dhandle,
- it->fslots + findx,
- (const char *) NULL);
- }
- }
- if (ftype == DEBUG_TYPE_NULL)
- return false;
-
- switch (flags & CXXFLAGS_VISIBILITY)
- {
- default:
- ieee_error (info, start, "unknown C++ visibility");
- return false;
-
- case CXXFLAGS_VISIBILITY_PUBLIC:
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
-
- case CXXFLAGS_VISIBILITY_PRIVATE:
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
-
- case CXXFLAGS_VISIBILITY_PROTECTED:
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- }
-
- if (staticp)
- {
- char *mangledcopy;
-
- mangledcopy = savestring (mangledname, mangledlen);
-
- field = debug_make_static_member (dhandle, fieldcopy,
- ftype, mangledcopy,
- visibility);
- }
- else
- {
- bfd_vma bitpos, bitsize;
-
- bitpos = debug_get_field_bitpos (dhandle, *pf);
- bitsize = debug_get_field_bitsize (dhandle, *pf);
- if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
- {
- ieee_error (info, start, "bad C++ field bit pos or size");
- return false;
- }
- field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
- bitsize, visibility);
- }
-
- if (field == DEBUG_FIELD_NULL)
- return false;
-
- if (field_count + 1 >= field_alloc)
- {
- field_alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, field_alloc * sizeof *fields));
- }
-
- fields[field_count] = field;
- ++field_count;
- fields[field_count] = DEBUG_FIELD_NULL;
- }
- break;
-
- case 'm':
- case 'v':
- {
- bfd_vma flags, voffset, control;
- const char *name, *mangled;
- unsigned long namlen, mangledlen;
- struct ieee_var *pv, *pvend;
- debug_type type;
- enum debug_visibility visibility;
- boolean constp, volatilep;
- char *mangledcopy;
- debug_method_variant mv;
- struct ieee_method *meth;
- unsigned int im;
-
- if (! ieee_require_asn (info, pp, &flags)
- || ! ieee_require_atn65 (info, pp, &name, &namlen)
- || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
- return false;
- count -= 3;
- if (id != 'v')
- voffset = 0;
- else
- {
- if (! ieee_require_asn (info, pp, &voffset))
- return false;
- --count;
- }
- if (! ieee_require_asn (info, pp, &control))
- return false;
- --count;
-
- /* We just ignore the control information. */
-
- /* We have no way to represent friend information, so we
- just ignore it. */
- if ((flags & CXXFLAGS_FRIEND) != 0)
- break;
-
- /* We should already have seen a type for the function. */
- pv = info->vars.vars;
- pvend = pv + info->vars.alloc;
- for (; pv < pvend; pv++)
- if (pv->namlen == mangledlen
- && strncmp (pv->name, mangled, mangledlen) == 0)
- break;
-
- if (pv >= pvend)
- {
- /* We won't have type information for this function if
- it is not included in this file. We don't try to
- handle this case. FIXME. */
- type = (debug_make_function_type
- (dhandle,
- ieee_builtin_type (info, start,
- (unsigned int) builtin_void),
- (debug_type *) NULL,
- false));
- }
- else
- {
- debug_type return_type;
- const debug_type *arg_types;
- boolean varargs;
-
- if (debug_get_type_kind (dhandle, pv->type)
- != DEBUG_KIND_FUNCTION)
- {
- ieee_error (info, start,
- "bad type for C++ method function");
- return false;
- }
-
- return_type = debug_get_return_type (dhandle, pv->type);
- arg_types = debug_get_parameter_types (dhandle, pv->type,
- &varargs);
- if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
- {
- ieee_error (info, start,
- "no type information for C++ method function");
- return false;
- }
-
- type = debug_make_method_type (dhandle, return_type, it->type,
- (debug_type *) arg_types,
- varargs);
- }
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- switch (flags & CXXFLAGS_VISIBILITY)
- {
- default:
- ieee_error (info, start, "unknown C++ visibility");
- return false;
-
- case CXXFLAGS_VISIBILITY_PUBLIC:
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
-
- case CXXFLAGS_VISIBILITY_PRIVATE:
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
-
- case CXXFLAGS_VISIBILITY_PROTECTED:
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- }
-
- constp = (flags & CXXFLAGS_CONST) != 0 ? true : false;
- volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false;
-
- mangledcopy = savestring (mangled, mangledlen);
-
- if ((flags & CXXFLAGS_STATIC) != 0)
- {
- if (id == 'v')
- {
- ieee_error (info, start, "C++ static virtual method");
- return false;
- }
- mv = debug_make_static_method_variant (dhandle, mangledcopy,
- type, visibility,
- constp, volatilep);
- }
- else
- {
- debug_type vcontext;
-
- if (id != 'v')
- vcontext = DEBUG_TYPE_NULL;
- else
- {
- /* FIXME: How can we calculate this correctly? */
- vcontext = it->type;
- }
- mv = debug_make_method_variant (dhandle, mangledcopy, type,
- visibility, constp,
- volatilep, voffset,
- vcontext);
- }
- if (mv == DEBUG_METHOD_VARIANT_NULL)
- return false;
-
- for (meth = methods, im = 0; im < methods_count; meth++, im++)
- if (meth->namlen == namlen
- && strncmp (meth->name, name, namlen) == 0)
- break;
- if (im >= methods_count)
- {
- if (methods_count >= methods_alloc)
- {
- methods_alloc += 10;
- methods = ((struct ieee_method *)
- xrealloc (methods,
- methods_alloc * sizeof *methods));
- }
- methods[methods_count].name = name;
- methods[methods_count].namlen = namlen;
- methods[methods_count].variants = NULL;
- methods[methods_count].count = 0;
- methods[methods_count].alloc = 0;
- meth = methods + methods_count;
- ++methods_count;
- }
-
- if (meth->count + 1 >= meth->alloc)
- {
- meth->alloc += 10;
- meth->variants = ((debug_method_variant *)
- xrealloc (meth->variants,
- (meth->alloc
- * sizeof *meth->variants)));
- }
-
- meth->variants[meth->count] = mv;
- ++meth->count;
- meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;
- }
- break;
-
- case 'o':
- {
- bfd_vma spec;
-
- /* We have no way to store this information, so we just
- ignore it. */
- if (! ieee_require_asn (info, pp, &spec))
- return false;
- --count;
- if ((spec & 4) != 0)
- {
- const char *filename;
- unsigned long filenamlen;
- bfd_vma lineno;
-
- if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)
- || ! ieee_require_asn (info, pp, &lineno))
- return false;
- count -= 2;
- }
- else if ((spec & 8) != 0)
- {
- const char *mangled;
- unsigned long mangledlen;
-
- if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
- return false;
- --count;
- }
- else
- {
- ieee_error (info, start,
- "unrecognized C++ object overhead spec");
- return false;
- }
- }
- break;
-
- case 'z':
- {
- const char *vname, *basename;
- unsigned long vnamelen, baselen;
- bfd_vma vsize, control;
-
- /* A virtual table pointer. */
-
- if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)
- || ! ieee_require_asn (info, pp, &vsize)
- || ! ieee_require_atn65 (info, pp, &basename, &baselen)
- || ! ieee_require_asn (info, pp, &control))
- return false;
- count -= 4;
-
- /* We just ignore the control number. We don't care what
- the virtual table name is. We have no way to store the
- virtual table size, and I don't think we care anyhow. */
-
- /* FIXME: We can't handle multiple virtual table pointers. */
-
- if (baselen == 0)
- ownvptr = true;
- else
- {
- char *basecopy;
-
- basecopy = savestring (basename, baselen);
- vptrbase = debug_find_tagged_type (dhandle, basecopy,
- DEBUG_KIND_ILLEGAL);
- free (basecopy);
- if (vptrbase == DEBUG_TYPE_NULL)
- {
- ieee_error (info, start, "undefined C++ vtable");
- return false;
- }
- }
- }
- break;
- }
- }
-
- /* Now that we have seen all the method variants, we can call
- debug_make_method for each one. */
-
- if (methods_count == 0)
- dmethods = NULL;
- else
- {
- unsigned int i;
-
- dmethods = ((debug_method *)
- xmalloc ((methods_count + 1) * sizeof *dmethods));
- for (i = 0; i < methods_count; i++)
- {
- char *namcopy;
-
- namcopy = savestring (methods[i].name, methods[i].namlen);
- dmethods[i] = debug_make_method (dhandle, namcopy,
- methods[i].variants);
- if (dmethods[i] == DEBUG_METHOD_NULL)
- return false;
- }
- dmethods[i] = DEBUG_METHOD_NULL;
- free (methods);
- }
-
- /* The struct type was created as an indirect type pointing at
- it->slot. We update it->slot to automatically update all
- references to this struct. */
- it->slot = debug_make_object_type (dhandle,
- class != 'u',
- debug_get_type_size (dhandle,
- it->slot),
- fields, baseclasses, dmethods,
- vptrbase, ownvptr);
- if (it->slot == DEBUG_TYPE_NULL)
- return false;
-
- return true;
-}
-
-/* Read C++ default argument value and reference type information. */
-
-static boolean
-ieee_read_cxx_defaults (info, pp, count)
- struct ieee_info *info;
- const bfd_byte **pp;
- unsigned long count;
-{
- const bfd_byte *start;
- const char *fnname;
- unsigned long fnlen;
- bfd_vma defcount;
-
- start = *pp;
-
- /* Giving the function name before the argument count is an addendum
- to the spec. The function name is demangled, though, so this
- record must always refer to the current function. */
-
- if (info->blockstack.bsp <= info->blockstack.stack
- || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
- {
- ieee_error (info, start, "C++ default values not in a function");
- return false;
- }
-
- if (! ieee_require_atn65 (info, pp, &fnname, &fnlen)
- || ! ieee_require_asn (info, pp, &defcount))
- return false;
- count -= 2;
-
- while (defcount-- > 0)
- {
- bfd_vma type, val;
- const char *strval;
- unsigned long strvallen;
-
- if (! ieee_require_asn (info, pp, &type))
- return false;
- --count;
-
- switch (type)
- {
- case 0:
- case 4:
- break;
-
- case 1:
- case 2:
- if (! ieee_require_asn (info, pp, &val))
- return false;
- --count;
- break;
-
- case 3:
- case 7:
- if (! ieee_require_atn65 (info, pp, &strval, &strvallen))
- return false;
- --count;
- break;
-
- default:
- ieee_error (info, start, "unrecognized C++ default type");
- return false;
- }
-
- /* We have no way to record the default argument values, so we
- just ignore them. FIXME. */
- }
-
- /* Any remaining arguments are indices of parameters that are really
- reference type. */
- if (count > 0)
- {
- PTR dhandle;
- debug_type *arg_slots;
-
- dhandle = info->dhandle;
- arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots;
- while (count-- > 0)
- {
- bfd_vma indx;
- debug_type target;
-
- if (! ieee_require_asn (info, pp, &indx))
- return false;
- /* The index is 1 based. */
- --indx;
- if (arg_slots == NULL
- || arg_slots[indx] == DEBUG_TYPE_NULL
- || (debug_get_type_kind (dhandle, arg_slots[indx])
- != DEBUG_KIND_POINTER))
- {
- ieee_error (info, start, "reference parameter is not a pointer");
- return false;
- }
-
- target = debug_get_target_type (dhandle, arg_slots[indx]);
- arg_slots[indx] = debug_make_reference_type (dhandle, target);
- if (arg_slots[indx] == DEBUG_TYPE_NULL)
- return false;
- }
- }
-
- return true;
-}
-
-/* Read a C++ reference definition. */
-
-static boolean
-ieee_read_reference (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *start;
- bfd_vma flags;
- const char *class, *name;
- unsigned long classlen, namlen;
- debug_type *pslot;
- debug_type target;
-
- start = *pp;
-
- if (! ieee_require_asn (info, pp, &flags))
- return false;
-
- /* Giving the class name before the member name is in an addendum to
- the spec. */
- if (flags == 3)
- {
- if (! ieee_require_atn65 (info, pp, &class, &classlen))
- return false;
- }
-
- if (! ieee_require_atn65 (info, pp, &name, &namlen))
- return false;
-
- pslot = NULL;
- if (flags != 3)
- {
- int pass;
-
- /* We search from the last variable indices to the first in
- hopes of finding local variables correctly. We search the
- local variables on the first pass, and the global variables
- on the second. FIXME: This probably won't work in all cases.
- On the other hand, I don't know what will. */
- for (pass = 0; pass < 2; pass++)
- {
- struct ieee_vars *vars;
- int i;
- struct ieee_var *pv = NULL;
-
- if (pass == 0)
- vars = &info->vars;
- else
- {
- vars = info->global_vars;
- if (vars == NULL)
- break;
- }
-
- for (i = (int) vars->alloc - 1; i >= 0; i--)
- {
- boolean found;
-
- pv = vars->vars + i;
-
- if (pv->pslot == NULL
- || pv->namlen != namlen
- || strncmp (pv->name, name, namlen) != 0)
- continue;
-
- found = false;
- switch (flags)
- {
- default:
- ieee_error (info, start,
- "unrecognized C++ reference type");
- return false;
-
- case 0:
- /* Global variable or function. */
- if (pv->kind == IEEE_GLOBAL
- || pv->kind == IEEE_EXTERNAL
- || pv->kind == IEEE_FUNCTION)
- found = true;
- break;
-
- case 1:
- /* Global static variable or function. */
- if (pv->kind == IEEE_STATIC
- || pv->kind == IEEE_FUNCTION)
- found = true;
- break;
-
- case 2:
- /* Local variable. */
- if (pv->kind == IEEE_LOCAL)
- found = true;
- break;
- }
-
- if (found)
- break;
- }
-
- if (i >= 0)
- {
- pslot = pv->pslot;
- break;
- }
- }
- }
- else
- {
- struct ieee_tag *it;
-
- for (it = info->tags; it != NULL; it = it->next)
- {
- if (it->name[0] == class[0]
- && strncmp (it->name, class, classlen) == 0
- && strlen (it->name) == classlen)
- {
- if (it->fslots != NULL)
- {
- const debug_field *pf;
- unsigned int findx;
-
- pf = debug_get_fields (info->dhandle, it->type);
- if (pf == NULL)
- {
- ieee_error (info, start,
- "C++ reference in class with no fields");
- return false;
- }
-
- for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++)
- {
- const char *fname;
-
- fname = debug_get_field_name (info->dhandle, *pf);
- if (fname == NULL)
- return false;
- if (strncmp (fname, name, namlen) == 0
- && strlen (fname) == namlen)
- {
- pslot = it->fslots + findx;
- break;
- }
- }
- }
-
- break;
- }
- }
- }
-
- if (pslot == NULL)
- {
- ieee_error (info, start, "C++ reference not found");
- return false;
- }
-
- /* We allocated the type of the object as an indirect type pointing
- to *pslot, which we can now update to be a reference type. */
- if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
- {
- ieee_error (info, start, "C++ reference is not pointer");
- return false;
- }
-
- target = debug_get_target_type (info->dhandle, *pslot);
- *pslot = debug_make_reference_type (info->dhandle, target);
- if (*pslot == DEBUG_TYPE_NULL)
- return false;
-
- return true;
-}
-
-/* Require an ASN record. */
-
-static boolean
-ieee_require_asn (info, pp, pv)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
-{
- const bfd_byte *start;
- ieee_record_enum_type c;
- bfd_vma varindx;
-
- start = *pp;
-
- c = (ieee_record_enum_type) **pp;
- if (c != ieee_e2_first_byte_enum)
- {
- ieee_error (info, start, "missing required ASN");
- return false;
- }
- ++*pp;
-
- c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
- if (c != ieee_asn_record_enum)
- {
- ieee_error (info, start, "missing required ASN");
- return false;
- }
- ++*pp;
-
- /* Just ignore the variable index. */
- if (! ieee_read_number (info, pp, &varindx))
- return false;
-
- return ieee_read_expression (info, pp, pv);
-}
-
-/* Require an ATN65 record. */
-
-static boolean
-ieee_require_atn65 (info, pp, pname, pnamlen)
- struct ieee_info *info;
- const bfd_byte **pp;
- const char **pname;
- unsigned long *pnamlen;
-{
- const bfd_byte *start;
- ieee_record_enum_type c;
- bfd_vma name_indx, type_indx, atn_code;
-
- start = *pp;
-
- c = (ieee_record_enum_type) **pp;
- if (c != ieee_at_record_enum)
- {
- ieee_error (info, start, "missing required ATN65");
- return false;
- }
- ++*pp;
-
- c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
- if (c != ieee_atn_record_enum)
- {
- ieee_error (info, start, "missing required ATN65");
- return false;
- }
- ++*pp;
-
- if (! ieee_read_number (info, pp, &name_indx)
- || ! ieee_read_number (info, pp, &type_indx)
- || ! ieee_read_number (info, pp, &atn_code))
- return false;
-
- /* Just ignore name_indx. */
-
- if (type_indx != 0 || atn_code != 65)
- {
- ieee_error (info, start, "bad ATN65 record");
- return false;
- }
-
- return ieee_read_id (info, pp, pname, pnamlen);
-}
-
-/* Convert a register number in IEEE debugging information into a
- generic register number. */
-
-static int
-ieee_regno_to_genreg (abfd, r)
- bfd *abfd;
- int r;
-{
- switch (bfd_get_arch (abfd))
- {
- case bfd_arch_m68k:
- /* For some reasons stabs adds 2 to the floating point register
- numbers. */
- if (r >= 16)
- r += 2;
- break;
-
- case bfd_arch_i960:
- /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
- 32 to 35 for fp0 to fp3. */
- --r;
- break;
-
- default:
- break;
- }
-
- return r;
-}
-
-/* Convert a generic register number to an IEEE specific one. */
-
-static int
-ieee_genreg_to_regno (abfd, r)
- bfd *abfd;
- int r;
-{
- switch (bfd_get_arch (abfd))
- {
- case bfd_arch_m68k:
- /* For some reason stabs add 2 to the floating point register
- numbers. */
- if (r >= 18)
- r -= 2;
- break;
-
- case bfd_arch_i960:
- /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
- 32 to 35 for fp0 to fp3. */
- ++r;
- break;
-
- default:
- break;
- }
-
- return r;
-}
-
-/* These routines build IEEE debugging information out of the generic
- debugging information. */
-
-/* We build the IEEE debugging information byte by byte. Rather than
- waste time copying data around, we use a linked list of buffers to
- hold the data. */
-
-#define IEEE_BUFSIZE (490)
-
-struct ieee_buf
-{
- /* Next buffer. */
- struct ieee_buf *next;
- /* Number of data bytes in this buffer. */
- unsigned int c;
- /* Bytes. */
- bfd_byte buf[IEEE_BUFSIZE];
-};
-
-/* A list of buffers. */
-
-struct ieee_buflist
-{
- /* Head of list. */
- struct ieee_buf *head;
- /* Tail--last buffer on list. */
- struct ieee_buf *tail;
-};
-
-/* In order to generate the BB11 blocks required by the HP emulator,
- we keep track of ranges of addresses which correspond to a given
- compilation unit. */
-
-struct ieee_range
-{
- /* Next range. */
- struct ieee_range *next;
- /* Low address. */
- bfd_vma low;
- /* High address. */
- bfd_vma high;
-};
-
-/* This structure holds information for a class on the type stack. */
-
-struct ieee_type_class
-{
- /* The name index in the debugging information. */
- unsigned int indx;
- /* The pmisc records for the class. */
- struct ieee_buflist pmiscbuf;
- /* The number of pmisc records. */
- unsigned int pmisccount;
- /* The name of the class holding the virtual table, if not this
- class. */
- const char *vclass;
- /* Whether this class holds its own virtual table. */
- boolean ownvptr;
- /* The largest virtual table offset seen so far. */
- bfd_vma voffset;
- /* The current method. */
- const char *method;
- /* Additional pmisc records used to record fields of reference type. */
- struct ieee_buflist refs;
-};
-
-/* This is how we store types for the writing routines. Most types
- are simply represented by a type index. */
-
-struct ieee_write_type
-{
- /* Type index. */
- unsigned int indx;
- /* The size of the type, if known. */
- unsigned int size;
- /* The name of the type, if any. */
- const char *name;
- /* If this is a function or method type, we build the type here, and
- only add it to the output buffers if we need it. */
- struct ieee_buflist fndef;
- /* If this is a struct, this is where the struct definition is
- built. */
- struct ieee_buflist strdef;
- /* If this is a class, this is where the class information is built. */
- struct ieee_type_class *classdef;
- /* Whether the type is unsigned. */
- unsigned int unsignedp : 1;
- /* Whether this is a reference type. */
- unsigned int referencep : 1;
- /* Whether this is in the local type block. */
- unsigned int localp : 1;
- /* Whether this is a duplicate struct definition which we are
- ignoring. */
- unsigned int ignorep : 1;
-};
-
-/* This is the type stack used by the debug writing routines. FIXME:
- We could generate more efficient output if we remembered when we
- have output a particular type before. */
-
-struct ieee_type_stack
-{
- /* Next entry on stack. */
- struct ieee_type_stack *next;
- /* Type information. */
- struct ieee_write_type type;
-};
-
-/* This is a list of associations between a name and some types.
- These are used for typedefs and tags. */
-
-struct ieee_name_type
-{
- /* Next type for this name. */
- struct ieee_name_type *next;
- /* ID number. For a typedef, this is the index of the type to which
- this name is typedefed. */
- unsigned int id;
- /* Type. */
- struct ieee_write_type type;
- /* If this is a tag which has not yet been defined, this is the
- kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */
- enum debug_type_kind kind;
-};
-
-/* We use a hash table to associate names and types. */
-
-struct ieee_name_type_hash_table
-{
- struct bfd_hash_table root;
-};
-
-struct ieee_name_type_hash_entry
-{
- struct bfd_hash_entry root;
- /* Information for this name. */
- struct ieee_name_type *types;
-};
-
-/* This is a list of enums. */
-
-struct ieee_defined_enum
-{
- /* Next enum. */
- struct ieee_defined_enum *next;
- /* Type index. */
- unsigned int indx;
- /* Whether this enum has been defined. */
- boolean defined;
- /* Tag. */
- const char *tag;
- /* Names. */
- const char **names;
- /* Values. */
- bfd_signed_vma *vals;
-};
-
-/* We keep a list of modified versions of types, so that we don't
- output them more than once. */
-
-struct ieee_modified_type
-{
- /* Pointer to this type. */
- unsigned int pointer;
- /* Function with unknown arguments returning this type. */
- unsigned int function;
- /* Const version of this type. */
- unsigned int const_qualified;
- /* Volatile version of this type. */
- unsigned int volatile_qualified;
- /* List of arrays of this type of various bounds. */
- struct ieee_modified_array_type *arrays;
-};
-
-/* A list of arrays bounds. */
-
-struct ieee_modified_array_type
-{
- /* Next array bounds. */
- struct ieee_modified_array_type *next;
- /* Type index with these bounds. */
- unsigned int indx;
- /* Low bound. */
- bfd_signed_vma low;
- /* High bound. */
- bfd_signed_vma high;
-};
-
-/* This is a list of pending function parameter information. We don't
- output them until we see the first block. */
-
-struct ieee_pending_parm
-{
- /* Next pending parameter. */
- struct ieee_pending_parm *next;
- /* Name. */
- const char *name;
- /* Type index. */
- unsigned int type;
- /* Whether the type is a reference. */
- boolean referencep;
- /* Kind. */
- enum debug_parm_kind kind;
- /* Value. */
- bfd_vma val;
-};
-
-/* This is the handle passed down by debug_write. */
-
-struct ieee_handle
-{
- /* BFD we are writing to. */
- bfd *abfd;
- /* Whether we got an error in a subroutine called via traverse or
- map_over_sections. */
- boolean error;
- /* Current data buffer list. */
- struct ieee_buflist *current;
- /* Current data buffer. */
- struct ieee_buf *curbuf;
- /* Filename of current compilation unit. */
- const char *filename;
- /* Module name of current compilation unit. */
- const char *modname;
- /* List of buffer for global types. */
- struct ieee_buflist global_types;
- /* List of finished data buffers. */
- struct ieee_buflist data;
- /* List of buffers for typedefs in the current compilation unit. */
- struct ieee_buflist types;
- /* List of buffers for variables and functions in the current
- compilation unit. */
- struct ieee_buflist vars;
- /* List of buffers for C++ class definitions in the current
- compilation unit. */
- struct ieee_buflist cxx;
- /* List of buffers for line numbers in the current compilation unit. */
- struct ieee_buflist linenos;
- /* Ranges for the current compilation unit. */
- struct ieee_range *ranges;
- /* Ranges for all debugging information. */
- struct ieee_range *global_ranges;
- /* Nested pending ranges. */
- struct ieee_range *pending_ranges;
- /* Type stack. */
- struct ieee_type_stack *type_stack;
- /* Next unallocated type index. */
- unsigned int type_indx;
- /* Next unallocated name index. */
- unsigned int name_indx;
- /* Typedefs. */
- struct ieee_name_type_hash_table typedefs;
- /* Tags. */
- struct ieee_name_type_hash_table tags;
- /* Enums. */
- struct ieee_defined_enum *enums;
- /* Modified versions of types. */
- struct ieee_modified_type *modified;
- /* Number of entries allocated in modified. */
- unsigned int modified_alloc;
- /* 4 byte complex type. */
- unsigned int complex_float_index;
- /* 8 byte complex type. */
- unsigned int complex_double_index;
- /* The depth of block nesting. This is 0 outside a function, and 1
- just after start_function is called. */
- unsigned int block_depth;
- /* The name of the current function. */
- const char *fnname;
- /* List of buffers for the type of the function we are currently
- writing out. */
- struct ieee_buflist fntype;
- /* List of buffers for the parameters of the function we are
- currently writing out. */
- struct ieee_buflist fnargs;
- /* Number of arguments written to fnargs. */
- unsigned int fnargcount;
- /* Pending function parameters. */
- struct ieee_pending_parm *pending_parms;
- /* Current line number filename. */
- const char *lineno_filename;
- /* Line number name index. */
- unsigned int lineno_name_indx;
- /* Filename of pending line number. */
- const char *pending_lineno_filename;
- /* Pending line number. */
- unsigned long pending_lineno;
- /* Address of pending line number. */
- bfd_vma pending_lineno_addr;
- /* Highest address seen at end of procedure. */
- bfd_vma highaddr;
-};
-
-static boolean ieee_init_buffer
- PARAMS ((struct ieee_handle *, struct ieee_buflist *));
-static boolean ieee_change_buffer
- PARAMS ((struct ieee_handle *, struct ieee_buflist *));
-static boolean ieee_append_buffer
- PARAMS ((struct ieee_handle *, struct ieee_buflist *,
- struct ieee_buflist *));
-static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int));
-static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int));
-static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma));
-static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *));
-static boolean ieee_write_asn
- PARAMS ((struct ieee_handle *, unsigned int, bfd_vma));
-static boolean ieee_write_atn65
- PARAMS ((struct ieee_handle *, unsigned int, const char *));
-static boolean ieee_push_type
- PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean,
- boolean));
-static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
-static void ieee_pop_unused_type PARAMS ((struct ieee_handle *));
-static unsigned int ieee_pop_type_used
- PARAMS ((struct ieee_handle *, boolean));
-static boolean ieee_add_range
- PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma));
-static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
-static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
-static boolean ieee_define_type
- PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean));
-static boolean ieee_define_named_type
- PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int,
- boolean, boolean, struct ieee_buflist *));
-static struct ieee_modified_type *ieee_get_modified_info
- PARAMS ((struct ieee_handle *, unsigned int));
-static struct bfd_hash_entry *ieee_name_type_newfunc
- PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static boolean ieee_write_undefined_tag
- PARAMS ((struct ieee_name_type_hash_entry *, PTR));
-static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *));
-static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR));
-static boolean ieee_add_bb11
- PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma));
-static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
-static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility));
-static boolean ieee_class_method_var
- PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean,
- boolean, boolean, bfd_vma, boolean));
-
-static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
-static boolean ieee_start_source PARAMS ((PTR, const char *));
-static boolean ieee_empty_type PARAMS ((PTR));
-static boolean ieee_void_type PARAMS ((PTR));
-static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
-static boolean ieee_float_type PARAMS ((PTR, unsigned int));
-static boolean ieee_complex_type PARAMS ((PTR, unsigned int));
-static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
-static boolean ieee_enum_type
- PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
-static boolean ieee_pointer_type PARAMS ((PTR));
-static boolean ieee_function_type PARAMS ((PTR, int, boolean));
-static boolean ieee_reference_type PARAMS ((PTR));
-static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
-static boolean ieee_array_type
- PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
-static boolean ieee_set_type PARAMS ((PTR, boolean));
-static boolean ieee_offset_type PARAMS ((PTR));
-static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
-static boolean ieee_const_type PARAMS ((PTR));
-static boolean ieee_volatile_type PARAMS ((PTR));
-static boolean ieee_start_struct_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
-static boolean ieee_struct_field
- PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
-static boolean ieee_end_struct_type PARAMS ((PTR));
-static boolean ieee_start_class_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
- boolean));
-static boolean ieee_class_static_member
- PARAMS ((PTR, const char *, const char *, enum debug_visibility));
-static boolean ieee_class_baseclass
- PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
-static boolean ieee_class_start_method PARAMS ((PTR, const char *));
-static boolean ieee_class_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
- bfd_vma, boolean));
-static boolean ieee_class_static_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
-static boolean ieee_class_end_method PARAMS ((PTR));
-static boolean ieee_end_class_type PARAMS ((PTR));
-static boolean ieee_typedef_type PARAMS ((PTR, const char *));
-static boolean ieee_tag_type
- PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
-static boolean ieee_typdef PARAMS ((PTR, const char *));
-static boolean ieee_tag PARAMS ((PTR, const char *));
-static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean ieee_float_constant PARAMS ((PTR, const char *, double));
-static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean ieee_variable
- PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
-static boolean ieee_start_function PARAMS ((PTR, const char *, boolean));
-static boolean ieee_function_parameter
- PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
-static boolean ieee_start_block PARAMS ((PTR, bfd_vma));
-static boolean ieee_end_block PARAMS ((PTR, bfd_vma));
-static boolean ieee_end_function PARAMS ((PTR));
-static boolean ieee_lineno
- PARAMS ((PTR, const char *, unsigned long, bfd_vma));
-
-static const struct debug_write_fns ieee_fns =
-{
- ieee_start_compilation_unit,
- ieee_start_source,
- ieee_empty_type,
- ieee_void_type,
- ieee_int_type,
- ieee_float_type,
- ieee_complex_type,
- ieee_bool_type,
- ieee_enum_type,
- ieee_pointer_type,
- ieee_function_type,
- ieee_reference_type,
- ieee_range_type,
- ieee_array_type,
- ieee_set_type,
- ieee_offset_type,
- ieee_method_type,
- ieee_const_type,
- ieee_volatile_type,
- ieee_start_struct_type,
- ieee_struct_field,
- ieee_end_struct_type,
- ieee_start_class_type,
- ieee_class_static_member,
- ieee_class_baseclass,
- ieee_class_start_method,
- ieee_class_method_variant,
- ieee_class_static_method_variant,
- ieee_class_end_method,
- ieee_end_class_type,
- ieee_typedef_type,
- ieee_tag_type,
- ieee_typdef,
- ieee_tag,
- ieee_int_constant,
- ieee_float_constant,
- ieee_typed_constant,
- ieee_variable,
- ieee_start_function,
- ieee_function_parameter,
- ieee_start_block,
- ieee_end_block,
- ieee_end_function,
- ieee_lineno
-};
-
-/* Initialize a buffer to be empty. */
-
-/*ARGSUSED*/
-static boolean
-ieee_init_buffer (info, buflist)
- struct ieee_handle *info;
- struct ieee_buflist *buflist;
-{
- buflist->head = NULL;
- buflist->tail = NULL;
- return true;
-}
-
-/* See whether a buffer list has any data. */
-
-#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL)
-
-/* Change the current buffer to a specified buffer chain. */
-
-static boolean
-ieee_change_buffer (info, buflist)
- struct ieee_handle *info;
- struct ieee_buflist *buflist;
-{
- if (buflist->head == NULL)
- {
- struct ieee_buf *buf;
-
- buf = (struct ieee_buf *) xmalloc (sizeof *buf);
- buf->next = NULL;
- buf->c = 0;
- buflist->head = buf;
- buflist->tail = buf;
- }
-
- info->current = buflist;
- info->curbuf = buflist->tail;
-
- return true;
-}
-
-/* Append a buffer chain. */
-
-/*ARGSUSED*/
-static boolean
-ieee_append_buffer (info, mainbuf, newbuf)
- struct ieee_handle *info;
- struct ieee_buflist *mainbuf;
- struct ieee_buflist *newbuf;
-{
- if (newbuf->head != NULL)
- {
- if (mainbuf->head == NULL)
- mainbuf->head = newbuf->head;
- else
- mainbuf->tail->next = newbuf->head;
- mainbuf->tail = newbuf->tail;
- }
- return true;
-}
-
-/* Write a byte into the buffer. We use a macro for speed and a
- function for the complex cases. */
-
-#define ieee_write_byte(info, b) \
- ((info)->curbuf->c < IEEE_BUFSIZE \
- ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \
- : ieee_real_write_byte ((info), (b)))
-
-static boolean
-ieee_real_write_byte (info, b)
- struct ieee_handle *info;
- int b;
-{
- if (info->curbuf->c >= IEEE_BUFSIZE)
- {
- struct ieee_buf *n;
-
- n = (struct ieee_buf *) xmalloc (sizeof *n);
- n->next = NULL;
- n->c = 0;
- if (info->current->head == NULL)
- info->current->head = n;
- else
- info->current->tail->next = n;
- info->current->tail = n;
- info->curbuf = n;
- }
-
- info->curbuf->buf[info->curbuf->c] = b;
- ++info->curbuf->c;
-
- return true;
-}
-
-/* Write out two bytes. */
-
-static boolean
-ieee_write_2bytes (info, i)
- struct ieee_handle *info;
- int i;
-{
- return (ieee_write_byte (info, i >> 8)
- && ieee_write_byte (info, i & 0xff));
-}
-
-/* Write out an integer. */
-
-static boolean
-ieee_write_number (info, v)
- struct ieee_handle *info;
- bfd_vma v;
-{
- bfd_vma t;
- bfd_byte ab[20];
- bfd_byte *p;
- unsigned int c;
-
- if (v <= (bfd_vma) ieee_number_end_enum)
- return ieee_write_byte (info, (int) v);
-
- t = v;
- p = ab + sizeof ab;
- while (t != 0)
- {
- *--p = t & 0xff;
- t >>= 8;
- }
- c = (ab + 20) - p;
-
- if (c > (unsigned int) (ieee_number_repeat_end_enum
- - ieee_number_repeat_start_enum))
- {
- fprintf (stderr, "IEEE numeric overflow: 0x");
- fprintf_vma (stderr, v);
- fprintf (stderr, "\n");
- return false;
- }
-
- if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c))
- return false;
- for (; c > 0; --c, ++p)
- {
- if (! ieee_write_byte (info, *p))
- return false;
- }
-
- return true;
-}
-
-/* Write out a string. */
-
-static boolean
-ieee_write_id (info, s)
- struct ieee_handle *info;
- const char *s;
-{
- unsigned int len;
-
- len = strlen (s);
- if (len <= 0x7f)
- {
- if (! ieee_write_byte (info, len))
- return false;
- }
- else if (len <= 0xff)
- {
- if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum)
- || ! ieee_write_byte (info, len))
- return false;
- }
- else if (len <= 0xffff)
- {
- if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum)
- || ! ieee_write_2bytes (info, len))
- return false;
- }
- else
- {
- fprintf (stderr, "IEEE string length overflow: %u\n", len);
- return false;
- }
-
- for (; *s != '\0'; s++)
- if (! ieee_write_byte (info, *s))
- return false;
-
- return true;
-}
-
-/* Write out an ASN record. */
-
-static boolean
-ieee_write_asn (info, indx, val)
- struct ieee_handle *info;
- unsigned int indx;
- bfd_vma val;
-{
- return (ieee_write_2bytes (info, (int) ieee_asn_record_enum)
- && ieee_write_number (info, indx)
- && ieee_write_number (info, val));
-}
-
-/* Write out an ATN65 record. */
-
-static boolean
-ieee_write_atn65 (info, indx, s)
- struct ieee_handle *info;
- unsigned int indx;
- const char *s;
-{
- return (ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- && ieee_write_number (info, indx)
- && ieee_write_number (info, 0)
- && ieee_write_number (info, 65)
- && ieee_write_id (info, s));
-}
-
-/* Push a type index onto the type stack. */
-
-static boolean
-ieee_push_type (info, indx, size, unsignedp, localp)
- struct ieee_handle *info;
- unsigned int indx;
- unsigned int size;
- boolean unsignedp;
- boolean localp;
-{
- struct ieee_type_stack *ts;
-
- ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
- memset (ts, 0, sizeof *ts);
-
- ts->type.indx = indx;
- ts->type.size = size;
- ts->type.unsignedp = unsignedp;
- ts->type.localp = localp;
-
- ts->next = info->type_stack;
- info->type_stack = ts;
-
- return true;
-}
-
-/* Pop a type index off the type stack. */
-
-static unsigned int
-ieee_pop_type (info)
- struct ieee_handle *info;
-{
- return ieee_pop_type_used (info, true);
-}
-
-/* Pop an unused type index off the type stack. */
-
-static void
-ieee_pop_unused_type (info)
- struct ieee_handle *info;
-{
- (void) ieee_pop_type_used (info, false);
-}
-
-/* Pop a used or unused type index off the type stack. */
-
-static unsigned int
-ieee_pop_type_used (info, used)
- struct ieee_handle *info;
- boolean used;
-{
- struct ieee_type_stack *ts;
- unsigned int ret;
-
- ts = info->type_stack;
- assert (ts != NULL);
-
- /* If this is a function type, and we need it, we need to append the
- actual definition to the typedef block now. */
- if (used && ! ieee_buffer_emptyp (&ts->type.fndef))
- {
- struct ieee_buflist *buflist;
-
- if (ts->type.localp)
- {
- /* Make sure we have started the types block. */
- if (ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
- buflist = &info->types;
- }
- else
- {
- /* Make sure we started the global type block. */
- if (ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- return false;
- }
- buflist = &info->global_types;
- }
-
- if (! ieee_append_buffer (info, buflist, &ts->type.fndef))
- return false;
- }
-
- ret = ts->type.indx;
- info->type_stack = ts->next;
- free (ts);
- return ret;
-}
-
-/* Add a range of bytes included in the current compilation unit. */
-
-static boolean
-ieee_add_range (info, global, low, high)
- struct ieee_handle *info;
- boolean global;
- bfd_vma low;
- bfd_vma high;
-{
- struct ieee_range **plist, *r, **pr;
-
- if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high)
- return true;
-
- if (global)
- plist = &info->global_ranges;
- else
- plist = &info->ranges;
-
- for (r = *plist; r != NULL; r = r->next)
- {
- if (high >= r->low && low <= r->high)
- {
- /* The new range overlaps r. */
- if (low < r->low)
- r->low = low;
- if (high > r->high)
- r->high = high;
- pr = &r->next;
- while (*pr != NULL && (*pr)->low <= r->high)
- {
- struct ieee_range *n;
-
- if ((*pr)->high > r->high)
- r->high = (*pr)->high;
- n = (*pr)->next;
- free (*pr);
- *pr = n;
- }
- return true;
- }
- }
-
- r = (struct ieee_range *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
-
- r->low = low;
- r->high = high;
-
- /* Store the ranges sorted by address. */
- for (pr = plist; *pr != NULL; pr = &(*pr)->next)
- if ((*pr)->low > high)
- break;
- r->next = *pr;
- *pr = r;
-
- return true;
-}
-
-/* Start a new range for which we only have the low address. */
-
-static boolean
-ieee_start_range (info, low)
- struct ieee_handle *info;
- bfd_vma low;
-{
- struct ieee_range *r;
-
- r = (struct ieee_range *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
- r->low = low;
- r->next = info->pending_ranges;
- info->pending_ranges = r;
- return true;
-}
-
-/* Finish a range started by ieee_start_range. */
-
-static boolean
-ieee_end_range (info, high)
- struct ieee_handle *info;
- bfd_vma high;
-{
- struct ieee_range *r;
- bfd_vma low;
-
- assert (info->pending_ranges != NULL);
- r = info->pending_ranges;
- low = r->low;
- info->pending_ranges = r->next;
- free (r);
- return ieee_add_range (info, false, low, high);
-}
-
-/* Start defining a type. */
-
-static boolean
-ieee_define_type (info, size, unsignedp, localp)
- struct ieee_handle *info;
- unsigned int size;
- boolean unsignedp;
- boolean localp;
-{
- return ieee_define_named_type (info, (const char *) NULL,
- (unsigned int) -1, size, unsignedp,
- localp, (struct ieee_buflist *) NULL);
-}
-
-/* Start defining a named type. */
-
-static boolean
-ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist)
- struct ieee_handle *info;
- const char *name;
- unsigned int indx;
- unsigned int size;
- boolean unsignedp;
- boolean localp;
- struct ieee_buflist *buflist;
-{
- unsigned int type_indx;
- unsigned int name_indx;
-
- if (indx != (unsigned int) -1)
- type_indx = indx;
- else
- {
- type_indx = info->type_indx;
- ++info->type_indx;
- }
-
- name_indx = info->name_indx;
- ++info->name_indx;
-
- if (name == NULL)
- name = "";
-
- /* If we were given a buffer, use it; otherwise, use either the
- local or the global type information, and make sure that the type
- block is started. */
- if (buflist != NULL)
- {
- if (! ieee_change_buffer (info, buflist))
- return false;
- }
- else if (localp)
- {
- if (! ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types))
- return false;
- }
- else
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
- }
- else
- {
- if (! ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types))
- return false;
- }
- else
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- return false;
- }
- }
-
- /* Push the new type on the type stack, write out an NN record, and
- write out the start of a TY record. The caller will then finish
- the TY record. */
- if (! ieee_push_type (info, type_indx, size, unsignedp, localp))
- return false;
-
- return (ieee_write_byte (info, (int) ieee_nn_record)
- && ieee_write_number (info, name_indx)
- && ieee_write_id (info, name)
- && ieee_write_byte (info, (int) ieee_ty_record_enum)
- && ieee_write_number (info, type_indx)
- && ieee_write_byte (info, 0xce)
- && ieee_write_number (info, name_indx));
-}
-
-/* Get an entry to the list of modified versions of a type. */
-
-static struct ieee_modified_type *
-ieee_get_modified_info (info, indx)
- struct ieee_handle *info;
- unsigned int indx;
-{
- if (indx >= info->modified_alloc)
- {
- unsigned int nalloc;
-
- nalloc = info->modified_alloc;
- if (nalloc == 0)
- nalloc = 16;
- while (indx >= nalloc)
- nalloc *= 2;
- info->modified = ((struct ieee_modified_type *)
- xrealloc (info->modified,
- nalloc * sizeof *info->modified));
- memset (info->modified + info->modified_alloc, 0,
- (nalloc - info->modified_alloc) * sizeof *info->modified);
- info->modified_alloc = nalloc;
- }
-
- return info->modified + indx;
-}
-
-/* Routines for the hash table mapping names to types. */
-
-/* Initialize an entry in the hash table. */
-
-static struct bfd_hash_entry *
-ieee_name_type_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
-{
- struct ieee_name_type_hash_entry *ret =
- (struct ieee_name_type_hash_entry *) entry;
-
- /* Allocate the structure if it has not already been allocated by a
- subclass. */
- if (ret == NULL)
- ret = ((struct ieee_name_type_hash_entry *)
- bfd_hash_allocate (table, sizeof *ret));
- if (ret == NULL)
- return NULL;
-
- /* Call the allocation method of the superclass. */
- ret = ((struct ieee_name_type_hash_entry *)
- bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
- if (ret)
- {
- /* Set local fields. */
- ret->types = NULL;
- }
-
- return (struct bfd_hash_entry *) ret;
-}
-
-/* Look up an entry in the hash table. */
-
-#define ieee_name_type_hash_lookup(table, string, create, copy) \
- ((struct ieee_name_type_hash_entry *) \
- bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
-
-/* Traverse the hash table. */
-
-#define ieee_name_type_hash_traverse(table, func, info) \
- (bfd_hash_traverse \
- (&(table)->root, \
- (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
- (info)))
-
-/* The general routine to write out IEEE debugging information. */
-
-boolean
-write_ieee_debugging_info (abfd, dhandle)
- bfd *abfd;
- PTR dhandle;
-{
- struct ieee_handle info;
- asection *s;
- const char *err;
- struct ieee_buf *b;
-
- memset (&info, 0, sizeof info);
- info.abfd = abfd;
- info.type_indx = 256;
- info.name_indx = 32;
-
- if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc)
- || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc))
- return false;
-
- if (! ieee_init_buffer (&info, &info.global_types)
- || ! ieee_init_buffer (&info, &info.data)
- || ! ieee_init_buffer (&info, &info.types)
- || ! ieee_init_buffer (&info, &info.vars)
- || ! ieee_init_buffer (&info, &info.cxx)
- || ! ieee_init_buffer (&info, &info.linenos)
- || ! ieee_init_buffer (&info, &info.fntype)
- || ! ieee_init_buffer (&info, &info.fnargs))
- return false;
-
- if (! debug_write (dhandle, &ieee_fns, (PTR) &info))
- return false;
-
- if (info.filename != NULL)
- {
- if (! ieee_finish_compilation_unit (&info))
- return false;
- }
-
- /* Put any undefined tags in the global typedef information. */
- info.error = false;
- ieee_name_type_hash_traverse (&info.tags,
- ieee_write_undefined_tag,
- (PTR) &info);
- if (info.error)
- return false;
-
- /* Prepend the global typedef information to the other data. */
- if (! ieee_buffer_emptyp (&info.global_types))
- {
- /* The HP debugger seems to have a bug in which it ignores the
- last entry in the global types, so we add a dummy entry. */
- if (! ieee_change_buffer (&info, &info.global_types)
- || ! ieee_write_byte (&info, (int) ieee_nn_record)
- || ! ieee_write_number (&info, info.name_indx)
- || ! ieee_write_id (&info, "")
- || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
- || ! ieee_write_number (&info, info.type_indx)
- || ! ieee_write_byte (&info, 0xce)
- || ! ieee_write_number (&info, info.name_indx)
- || ! ieee_write_number (&info, 'P')
- || ! ieee_write_number (&info, (int) builtin_void + 32)
- || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
- return false;
-
- if (! ieee_append_buffer (&info, &info.global_types, &info.data))
- return false;
- info.data = info.global_types;
- }
-
- /* Make sure that we have declare BB11 blocks for each range in the
- file. They are added to info->vars. */
- info.error = false;
- if (! ieee_init_buffer (&info, &info.vars))
- return false;
- bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info);
- if (info.error)
- return false;
- if (! ieee_buffer_emptyp (&info.vars))
- {
- if (! ieee_change_buffer (&info, &info.vars)
- || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
- return false;
-
- if (! ieee_append_buffer (&info, &info.data, &info.vars))
- return false;
- }
-
- /* Now all the data is in info.data. Write it out to the BFD. We
- normally would need to worry about whether all the other sections
- are set up yet, but the IEEE backend will handle this particular
- case correctly regardless. */
- if (ieee_buffer_emptyp (&info.data))
- {
- /* There is no debugging information. */
- return true;
- }
- err = NULL;
- s = bfd_make_section (abfd, ".debug");
- if (s == NULL)
- err = "bfd_make_section";
- if (err == NULL)
- {
- if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS))
- err = "bfd_set_section_flags";
- }
- if (err == NULL)
- {
- bfd_size_type size;
-
- size = 0;
- for (b = info.data.head; b != NULL; b = b->next)
- size += b->c;
- if (! bfd_set_section_size (abfd, s, size))
- err = "bfd_set_section_size";
- }
- if (err == NULL)
- {
- file_ptr offset;
-
- offset = 0;
- for (b = info.data.head; b != NULL; b = b->next)
- {
- if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c))
- {
- err = "bfd_set_section_contents";
- break;
- }
- offset += b->c;
- }
- }
-
- if (err != NULL)
- {
- fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err,
- bfd_errmsg (bfd_get_error ()));
- return false;
- }
-
- bfd_hash_table_free (&info.typedefs.root);
- bfd_hash_table_free (&info.tags.root);
-
- return true;
-}
-
-/* Write out information for an undefined tag. This is called via
- ieee_name_type_hash_traverse. */
-
-static boolean
-ieee_write_undefined_tag (h, p)
- struct ieee_name_type_hash_entry *h;
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_name_type *nt;
-
- for (nt = h->types; nt != NULL; nt = nt->next)
- {
- unsigned int name_indx;
- char code;
-
- if (nt->kind == DEBUG_KIND_ILLEGAL)
- continue;
-
- if (ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- {
- info->error = true;
- return false;
- }
- }
- else
- {
- if (! ieee_change_buffer (info, &info->global_types))
- {
- info->error = true;
- return false;
- }
- }
-
- name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, name_indx)
- || ! ieee_write_id (info, nt->type.name)
- || ! ieee_write_byte (info, (int) ieee_ty_record_enum)
- || ! ieee_write_number (info, nt->type.indx)
- || ! ieee_write_byte (info, 0xce)
- || ! ieee_write_number (info, name_indx))
- {
- info->error = true;
- return false;
- }
-
- switch (nt->kind)
- {
- default:
- abort ();
- info->error = true;
- return false;
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_CLASS:
- code = 'S';
- break;
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_UNION_CLASS:
- code = 'U';
- break;
- case DEBUG_KIND_ENUM:
- code = 'E';
- break;
- }
- if (! ieee_write_number (info, code)
- || ! ieee_write_number (info, 0))
- {
- info->error = true;
- return false;
- }
- }
-
- return true;
-}
-
-/* Start writing out information for a compilation unit. */
-
-static boolean
-ieee_start_compilation_unit (p, filename)
- PTR p;
- const char *filename;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- const char *modname;
- char *c, *s;
- unsigned int nindx;
-
- if (info->filename != NULL)
- {
- if (! ieee_finish_compilation_unit (info))
- return false;
- }
-
- info->filename = filename;
- modname = strrchr (filename, '/');
- if (modname != NULL)
- ++modname;
- else
- {
- modname = strrchr (filename, '\\');
- if (modname != NULL)
- ++modname;
- else
- modname = filename;
- }
- c = xstrdup (modname);
- s = strrchr (c, '.');
- if (s != NULL)
- *s = '\0';
- info->modname = c;
-
- if (! ieee_init_buffer (info, &info->types)
- || ! ieee_init_buffer (info, &info->vars)
- || ! ieee_init_buffer (info, &info->cxx)
- || ! ieee_init_buffer (info, &info->linenos))
- return false;
- info->ranges = NULL;
-
- /* Always include a BB1 and a BB3 block. That is what the output of
- the MRI linker seems to look like. */
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
-
- nindx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 3)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
-
- return true;
-}
-
-/* Finish up a compilation unit. */
-
-static boolean
-ieee_finish_compilation_unit (info)
- struct ieee_handle *info;
-{
- struct ieee_range *r;
-
- if (! ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- }
-
- if (! ieee_buffer_emptyp (&info->cxx))
- {
- /* Append any C++ information to the global function and
- variable information. */
- assert (! ieee_buffer_emptyp (&info->vars));
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- /* We put the pmisc records in a dummy procedure, just as the
- MRI compiler does. */
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 6)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "__XRYCPP")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, info->highaddr - 1)
- || ! ieee_append_buffer (info, &info->vars, &info->cxx)
- || ! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, info->highaddr - 1))
- return false;
- }
-
- if (! ieee_buffer_emptyp (&info->vars))
- {
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- }
-
- if (info->pending_lineno_filename != NULL)
- {
- /* Force out the pending line number. */
- if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1))
- return false;
- }
- if (! ieee_buffer_emptyp (&info->linenos))
- {
- if (! ieee_change_buffer (info, &info->linenos)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- if (strcmp (info->filename, info->lineno_filename) != 0)
- {
- /* We were not in the main file. We just closed the
- included line number block, and now we must close the
- main line number block. */
- if (! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- }
- }
-
- if (! ieee_append_buffer (info, &info->data, &info->types)
- || ! ieee_append_buffer (info, &info->data, &info->vars)
- || ! ieee_append_buffer (info, &info->data, &info->linenos))
- return false;
-
- /* Build BB10/BB11 blocks based on the ranges we recorded. */
- if (! ieee_change_buffer (info, &info->data))
- return false;
-
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 10)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "GNU objcopy"))
- return false;
-
- for (r = info->ranges; r != NULL; r = r->next)
- {
- bfd_vma low, high;
- asection *s;
- int kind;
-
- low = r->low;
- high = r->high;
-
- /* Find the section corresponding to this range. */
- for (s = info->abfd->sections; s != NULL; s = s->next)
- {
- if (bfd_get_section_vma (info->abfd, s) <= low
- && high <= (bfd_get_section_vma (info->abfd, s)
- + bfd_section_size (info->abfd, s)))
- break;
- }
-
- if (s == NULL)
- {
- /* Just ignore this range. */
- continue;
- }
-
- /* Coalesce ranges if it seems reasonable. */
- while (r->next != NULL
- && high + 0x1000 >= r->next->low
- && (r->next->high
- <= (bfd_get_section_vma (info->abfd, s)
- + bfd_section_size (info->abfd, s))))
- {
- r = r->next;
- high = r->high;
- }
-
- if ((s->flags & SEC_CODE) != 0)
- kind = 1;
- else if ((s->flags & SEC_READONLY) != 0)
- kind = 3;
- else
- kind = 2;
-
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 11)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, kind)
- || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE)
- || ! ieee_write_number (info, low)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, high - low))
- return false;
-
- /* Add this range to the list of global ranges. */
- if (! ieee_add_range (info, true, low, high))
- return false;
- }
-
- if (! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
-
- return true;
-}
-
-/* Add BB11 blocks describing each range that we have not already
- described. */
-
-static void
-ieee_add_bb11_blocks (abfd, sec, data)
- bfd *abfd;
- asection *sec;
- PTR data;
-{
- struct ieee_handle *info = (struct ieee_handle *) data;
- bfd_vma low, high;
- struct ieee_range *r;
-
- low = bfd_get_section_vma (abfd, sec);
- high = low + bfd_section_size (abfd, sec);
-
- /* Find the first range at or after this section. The ranges are
- sorted by address. */
- for (r = info->global_ranges; r != NULL; r = r->next)
- if (r->high > low)
- break;
-
- while (low < high)
- {
- if (r == NULL || r->low >= high)
- {
- if (! ieee_add_bb11 (info, sec, low, high))
- info->error = true;
- return;
- }
-
- if (low < r->low
- && r->low - low > 0x100)
- {
- if (! ieee_add_bb11 (info, sec, low, r->low))
- {
- info->error = true;
- return;
- }
- }
- low = r->high;
-
- r = r->next;
- }
-}
-
-/* Add a single BB11 block for a range. We add it to info->vars. */
-
-static boolean
-ieee_add_bb11 (info, sec, low, high)
- struct ieee_handle *info;
- asection *sec;
- bfd_vma low;
- bfd_vma high;
-{
- int kind;
-
- if (! ieee_buffer_emptyp (&info->vars))
- {
- if (! ieee_change_buffer (info, &info->vars))
- return false;
- }
- else
- {
- const char *filename, *modname;
- char *c, *s;
-
- /* Start the enclosing BB10 block. */
- filename = bfd_get_filename (info->abfd);
- modname = strrchr (filename, '/');
- if (modname != NULL)
- ++modname;
- else
- {
- modname = strrchr (filename, '\\');
- if (modname != NULL)
- ++modname;
- else
- modname = filename;
- }
- c = xstrdup (modname);
- s = strrchr (c, '.');
- if (s != NULL)
- *s = '\0';
-
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 10)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, c)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "GNU objcopy"))
- return false;
-
- free (c);
- }
-
- if ((sec->flags & SEC_CODE) != 0)
- kind = 1;
- else if ((sec->flags & SEC_READONLY) != 0)
- kind = 3;
- else
- kind = 2;
-
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 11)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, kind)
- || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE)
- || ! ieee_write_number (info, low)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, high - low))
- return false;
-
- return true;
-}
-
-/* Start recording information from a particular source file. This is
- used to record which file defined which types, variables, etc. It
- is not used for line numbers, since the lineno entry point passes
- down the file name anyhow. IEEE debugging information doesn't seem
- to store this information anywhere. */
-
-/*ARGSUSED*/
-static boolean
-ieee_start_source (p, filename)
- PTR p;
- const char *filename;
-{
- return true;
-}
-
-/* Make an empty type. */
-
-static boolean
-ieee_empty_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
-}
-
-/* Make a void type. */
-
-static boolean
-ieee_void_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_push_type (info, (int) builtin_void, 0, false, false);
-}
-
-/* Make an integer type. */
-
-static boolean
-ieee_int_type (p, size, unsignedp)
- PTR p;
- unsigned int size;
- boolean unsignedp;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int indx;
-
- switch (size)
- {
- case 1:
- indx = (int) builtin_signed_char;
- break;
- case 2:
- indx = (int) builtin_signed_short_int;
- break;
- case 4:
- indx = (int) builtin_signed_long;
- break;
- case 8:
- indx = (int) builtin_signed_long_long;
- break;
- default:
- fprintf (stderr, "IEEE unsupported integer type size %u\n", size);
- return false;
- }
-
- if (unsignedp)
- ++indx;
-
- return ieee_push_type (info, indx, size, unsignedp, false);
-}
-
-/* Make a floating point type. */
-
-static boolean
-ieee_float_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int indx;
-
- switch (size)
- {
- case 4:
- indx = (int) builtin_float;
- break;
- case 8:
- indx = (int) builtin_double;
- break;
- case 12:
- /* FIXME: This size really depends upon the processor. */
- indx = (int) builtin_long_double;
- break;
- case 16:
- indx = (int) builtin_long_long_double;
- break;
- default:
- fprintf (stderr, "IEEE unsupported float type size %u\n", size);
- return false;
- }
-
- return ieee_push_type (info, indx, size, false, false);
-}
-
-/* Make a complex type. */
-
-static boolean
-ieee_complex_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- char code;
-
- switch (size)
- {
- case 4:
- if (info->complex_float_index != 0)
- return ieee_push_type (info, info->complex_float_index, size * 2,
- false, false);
- code = 'c';
- break;
- case 12:
- case 16:
- /* These cases can be output by gcc -gstabs. Outputting the
- wrong type is better than crashing. */
- case 8:
- if (info->complex_double_index != 0)
- return ieee_push_type (info, info->complex_double_index, size * 2,
- false, false);
- code = 'd';
- break;
- default:
- fprintf (stderr, "IEEE unsupported complex type size %u\n", size);
- return false;
- }
-
- /* FIXME: I don't know what the string is for. */
- if (! ieee_define_type (info, size * 2, false, false)
- || ! ieee_write_number (info, code)
- || ! ieee_write_id (info, ""))
- return false;
-
- if (size == 4)
- info->complex_float_index = info->type_stack->type.indx;
- else
- info->complex_double_index = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a boolean type. IEEE doesn't support these, so we just make
- an integer type instead. */
-
-static boolean
-ieee_bool_type (p, size)
- PTR p;
- unsigned int size;
-{
- return ieee_int_type (p, size, true);
-}
-
-/* Make an enumeration. */
-
-static boolean
-ieee_enum_type (p, tag, names, vals)
- PTR p;
- const char *tag;
- const char **names;
- bfd_signed_vma *vals;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_defined_enum *e;
- boolean localp, simple;
- unsigned int indx;
- int i = 0;
-
- localp = false;
- indx = (unsigned int) -1;
- for (e = info->enums; e != NULL; e = e->next)
- {
- if (tag == NULL)
- {
- if (e->tag != NULL)
- continue;
- }
- else
- {
- if (e->tag == NULL
- || tag[0] != e->tag[0]
- || strcmp (tag, e->tag) != 0)
- continue;
- }
-
- if (! e->defined)
- {
- /* This enum tag has been seen but not defined. */
- indx = e->indx;
- break;
- }
-
- if (names != NULL && e->names != NULL)
- {
- for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
- {
- if (names[i][0] != e->names[i][0]
- || vals[i] != e->vals[i]
- || strcmp (names[i], e->names[i]) != 0)
- break;
- }
- }
-
- if ((names == NULL && e->names == NULL)
- || (names != NULL
- && e->names != NULL
- && names[i] == NULL
- && e->names[i] == NULL))
- {
- /* We've seen this enum before. */
- return ieee_push_type (info, e->indx, 0, true, false);
- }
-
- if (tag != NULL)
- {
- /* We've already seen an enum of the same name, so we must make
- sure to output this one locally. */
- localp = true;
- break;
- }
- }
-
- /* If this is a simple enumeration, in which the values start at 0
- and always increment by 1, we can use type E. Otherwise we must
- use type N. */
-
- simple = true;
- if (names != NULL)
- {
- for (i = 0; names[i] != NULL; i++)
- {
- if (vals[i] != i)
- {
- simple = false;
- break;
- }
- }
- }
-
- if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
- (struct ieee_buflist *) NULL)
- || ! ieee_write_number (info, simple ? 'E' : 'N'))
- return false;
- if (simple)
- {
- /* FIXME: This is supposed to be the enumeration size, but we
- don't store that. */
- if (! ieee_write_number (info, 4))
- return false;
- }
- if (names != NULL)
- {
- for (i = 0; names[i] != NULL; i++)
- {
- if (! ieee_write_id (info, names[i]))
- return false;
- if (! simple)
- {
- if (! ieee_write_number (info, vals[i]))
- return false;
- }
- }
- }
-
- if (! localp)
- {
- if (indx == (unsigned int) -1)
- {
- e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
- e->indx = info->type_stack->type.indx;
- e->tag = tag;
-
- e->next = info->enums;
- info->enums = e;
- }
-
- e->names = names;
- e->vals = vals;
- e->defined = true;
- }
-
- return true;
-}
-
-/* Make a pointer type. */
-
-static boolean
-ieee_pointer_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- unsigned int indx;
- struct ieee_modified_type *m = NULL;
-
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- /* A pointer to a simple builtin type can be obtained by adding 32.
- FIXME: Will this be a short pointer, and will that matter? */
- if (indx < 32)
- return ieee_push_type (info, indx + 32, 0, true, false);
-
- if (! localp)
- {
- m = ieee_get_modified_info (p, indx);
- if (m == NULL)
- return false;
-
- /* FIXME: The size should depend upon the architecture. */
- if (m->pointer > 0)
- return ieee_push_type (info, m->pointer, 4, true, false);
- }
-
- if (! ieee_define_type (info, 4, true, localp)
- || ! ieee_write_number (info, 'P')
- || ! ieee_write_number (info, indx))
- return false;
-
- if (! localp)
- m->pointer = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a function type. This will be called for a method, but we
- don't want to actually add it to the type table in that case. We
- handle this by defining the type in a private buffer, and only
- adding that buffer to the typedef block if we are going to use it. */
-
-static boolean
-ieee_function_type (p, argcount, varargs)
- PTR p;
- int argcount;
- boolean varargs;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- unsigned int *args = NULL;
- int i;
- unsigned int retindx;
- struct ieee_buflist fndef;
- struct ieee_modified_type *m;
-
- localp = false;
-
- if (argcount > 0)
- {
- args = (unsigned int *) xmalloc (argcount * sizeof *args);
- for (i = argcount - 1; i >= 0; i--)
- {
- if (info->type_stack->type.localp)
- localp = true;
- args[i] = ieee_pop_type (info);
- }
- }
- else if (argcount < 0)
- varargs = false;
-
- if (info->type_stack->type.localp)
- localp = true;
- retindx = ieee_pop_type (info);
-
- m = NULL;
- if (argcount < 0 && ! localp)
- {
- m = ieee_get_modified_info (p, retindx);
- if (m == NULL)
- return false;
-
- if (m->function > 0)
- return ieee_push_type (info, m->function, 0, true, false);
- }
-
- /* An attribute of 0x41 means that the frame and push mask are
- unknown. */
- if (! ieee_init_buffer (info, &fndef)
- || ! ieee_define_named_type (info, (const char *) NULL,
- (unsigned int) -1, 0, true, localp,
- &fndef)
- || ! ieee_write_number (info, 'x')
- || ! ieee_write_number (info, 0x41)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, retindx)
- || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
- return false;
- if (argcount > 0)
- {
- for (i = 0; i < argcount; i++)
- if (! ieee_write_number (info, args[i]))
- return false;
- free (args);
- }
- if (varargs)
- {
- /* A varargs function is represented by writing out the last
- argument as type void *, although this makes little sense. */
- if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
- return false;
- }
-
- if (! ieee_write_number (info, 0))
- return false;
-
- /* We wrote the information into fndef, in case we don't need it.
- It will be appended to info->types by ieee_pop_type. */
- info->type_stack->type.fndef = fndef;
-
- if (m != NULL)
- m->function = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a reference type. */
-
-static boolean
-ieee_reference_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* IEEE appears to record a normal pointer type, and then use a
- pmisc record to indicate that it is really a reference. */
-
- if (! ieee_pointer_type (p))
- return false;
- info->type_stack->type.referencep = true;
- return true;
-}
-
-/* Make a range type. */
-
-static boolean
-ieee_range_type (p, low, high)
- PTR p;
- bfd_signed_vma low;
- bfd_signed_vma high;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp, localp;
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- localp = info->type_stack->type.localp;
- ieee_pop_unused_type (info);
- return (ieee_define_type (info, size, unsignedp, localp)
- && ieee_write_number (info, 'R')
- && ieee_write_number (info, (bfd_vma) low)
- && ieee_write_number (info, (bfd_vma) high)
- && ieee_write_number (info, unsignedp ? 0 : 1)
- && ieee_write_number (info, size));
-}
-
-/* Make an array type. */
-
-/*ARGSUSED*/
-static boolean
-ieee_array_type (p, low, high, stringp)
- PTR p;
- bfd_signed_vma low;
- bfd_signed_vma high;
- boolean stringp;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int eleindx;
- boolean localp;
- unsigned int size;
- struct ieee_modified_type *m = NULL;
- struct ieee_modified_array_type *a;
-
- /* IEEE does not store the range, so we just ignore it. */
- ieee_pop_unused_type (info);
- localp = info->type_stack->type.localp;
- size = info->type_stack->type.size;
- eleindx = ieee_pop_type (info);
-
- /* If we don't know the range, treat the size as exactly one
- element. */
- if (low < high)
- size *= (high - low) + 1;
-
- if (! localp)
- {
- m = ieee_get_modified_info (info, eleindx);
- if (m == NULL)
- return false;
-
- for (a = m->arrays; a != NULL; a = a->next)
- {
- if (a->low == low && a->high == high)
- return ieee_push_type (info, a->indx, size, false, false);
- }
- }
-
- if (! ieee_define_type (info, size, false, localp)
- || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
- || ! ieee_write_number (info, eleindx))
- return false;
- if (low != 0)
- {
- if (! ieee_write_number (info, low))
- return false;
- }
-
- if (! ieee_write_number (info, high + 1))
- return false;
-
- if (! localp)
- {
- a = (struct ieee_modified_array_type *) xmalloc (sizeof *a);
- memset (a, 0, sizeof *a);
-
- a->indx = info->type_stack->type.indx;
- a->low = low;
- a->high = high;
-
- a->next = m->arrays;
- m->arrays = a;
- }
-
- return true;
-}
-
-/* Make a set type. */
-
-static boolean
-ieee_set_type (p, bitstringp)
- PTR p;
- boolean bitstringp;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- unsigned int eleindx;
-
- localp = info->type_stack->type.localp;
- eleindx = ieee_pop_type (info);
-
- /* FIXME: We don't know the size, so we just use 4. */
-
- return (ieee_define_type (info, 0, true, localp)
- && ieee_write_number (info, 's')
- && ieee_write_number (info, 4)
- && ieee_write_number (info, eleindx));
-}
-
-/* Make an offset type. */
-
-static boolean
-ieee_offset_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int targetindx, baseindx;
-
- targetindx = ieee_pop_type (info);
- baseindx = ieee_pop_type (info);
-
- /* FIXME: The MRI C++ compiler does not appear to generate any
- useful type information about an offset type. It just records a
- pointer to member as an integer. The MRI/HP IEEE spec does
- describe a pmisc record which can be used for a pointer to
- member. Unfortunately, it does not describe the target type,
- which seems pretty important. I'm going to punt this for now. */
-
- return ieee_int_type (p, 4, true);
-}
-
-/* Make a method type. */
-
-static boolean
-ieee_method_type (p, domain, argcount, varargs)
- PTR p;
- boolean domain;
- int argcount;
- boolean varargs;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
- method, but the definition is incomplete. We just output an 'x'
- type. */
-
- if (domain)
- ieee_pop_unused_type (info);
-
- return ieee_function_type (p, argcount, varargs);
-}
-
-/* Make a const qualified type. */
-
-static boolean
-ieee_const_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp, localp;
- unsigned int indx;
- struct ieee_modified_type *m = NULL;
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- if (! localp)
- {
- m = ieee_get_modified_info (info, indx);
- if (m == NULL)
- return false;
-
- if (m->const_qualified > 0)
- return ieee_push_type (info, m->const_qualified, size, unsignedp,
- false);
- }
-
- if (! ieee_define_type (info, size, unsignedp, localp)
- || ! ieee_write_number (info, 'n')
- || ! ieee_write_number (info, 1)
- || ! ieee_write_number (info, indx))
- return false;
-
- if (! localp)
- m->const_qualified = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a volatile qualified type. */
-
-static boolean
-ieee_volatile_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp, localp;
- unsigned int indx;
- struct ieee_modified_type *m = NULL;
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- if (! localp)
- {
- m = ieee_get_modified_info (info, indx);
- if (m == NULL)
- return false;
-
- if (m->volatile_qualified > 0)
- return ieee_push_type (info, m->volatile_qualified, size, unsignedp,
- false);
- }
-
- if (! ieee_define_type (info, size, unsignedp, localp)
- || ! ieee_write_number (info, 'n')
- || ! ieee_write_number (info, 2)
- || ! ieee_write_number (info, indx))
- return false;
-
- if (! localp)
- m->volatile_qualified = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Convert an enum debug_visibility into a CXXFLAGS value. */
-
-static unsigned int
-ieee_vis_to_flags (visibility)
- enum debug_visibility visibility;
-{
- switch (visibility)
- {
- default:
- abort ();
- case DEBUG_VISIBILITY_PUBLIC:
- return CXXFLAGS_VISIBILITY_PUBLIC;
- case DEBUG_VISIBILITY_PRIVATE:
- return CXXFLAGS_VISIBILITY_PRIVATE;
- case DEBUG_VISIBILITY_PROTECTED:
- return CXXFLAGS_VISIBILITY_PROTECTED;
- }
- /*NOTREACHED*/
-}
-
-/* Start defining a struct type. We build it in the strdef field on
- the stack, to avoid confusing type definitions required by the
- fields with the struct type itself. */
-
-static boolean
-ieee_start_struct_type (p, tag, id, structp, size)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp, ignorep;
- boolean copy;
- char ab[20];
- const char *look;
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt, *ntlook;
- struct ieee_buflist strdef;
-
- localp = false;
- ignorep = false;
-
- /* We need to create a tag for internal use even if we don't want
- one for external use. This will let us refer to an anonymous
- struct. */
- if (tag != NULL)
- {
- look = tag;
- copy = false;
- }
- else
- {
- sprintf (ab, "__anon%u", id);
- look = ab;
- copy = true;
- }
-
- /* If we already have references to the tag, we must use the
- existing type index. */
- h = ieee_name_type_hash_lookup (&info->tags, look, true, copy);
- if (h == NULL)
- return false;
-
- nt = NULL;
- for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next)
- {
- if (ntlook->id == id)
- nt = ntlook;
- else if (! ntlook->type.localp)
- {
- /* We are creating a duplicate definition of a globally
- defined tag. Force it to be local to avoid
- confusion. */
- localp = true;
- }
- }
-
- if (nt != NULL)
- {
- assert (localp == nt->type.localp);
- if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp)
- {
- /* We've already seen a global definition of the type.
- Ignore this new definition. */
- ignorep = true;
- }
- }
- else
- {
- nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
- memset (nt, 0, sizeof *nt);
- nt->id = id;
- nt->type.name = h->root.string;
- nt->next = h->types;
- h->types = nt;
- nt->type.indx = info->type_indx;
- ++info->type_indx;
- }
-
- nt->kind = DEBUG_KIND_ILLEGAL;
-
- if (! ieee_init_buffer (info, &strdef)
- || ! ieee_define_named_type (info, tag, nt->type.indx, size, true,
- localp, &strdef)
- || ! ieee_write_number (info, structp ? 'S' : 'U')
- || ! ieee_write_number (info, size))
- return false;
-
- if (! ignorep)
- {
- const char *hold;
-
- /* We never want nt->type.name to be NULL. We want the rest of
- the type to be the object set up on the type stack; it will
- have a NULL name if tag is NULL. */
- hold = nt->type.name;
- nt->type = info->type_stack->type;
- nt->type.name = hold;
- }
-
- info->type_stack->type.name = tag;
- info->type_stack->type.strdef = strdef;
- info->type_stack->type.ignorep = ignorep;
-
- return true;
-}
-
-/* Add a field to a struct. */
-
-static boolean
-ieee_struct_field (p, name, bitpos, bitsize, visibility)
- PTR p;
- const char *name;
- bfd_vma bitpos;
- bfd_vma bitsize;
- enum debug_visibility visibility;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp;
- boolean referencep;
- boolean localp;
- unsigned int indx;
- bfd_vma offset;
-
- assert (info->type_stack != NULL
- && info->type_stack->next != NULL
- && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
-
- /* If we are ignoring this struct definition, just pop and ignore
- the type. */
- if (info->type_stack->next->type.ignorep)
- {
- ieee_pop_unused_type (info);
- return true;
- }
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- referencep = info->type_stack->type.referencep;
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- if (localp)
- info->type_stack->type.localp = true;
-
- if (info->type_stack->type.classdef != NULL)
- {
- unsigned int flags;
- unsigned int nindx;
-
- /* This is a class. We must add a description of this field to
- the class records we are building. */
-
- flags = ieee_vis_to_flags (visibility);
- nindx = info->type_stack->type.classdef->indx;
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'd')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx, name)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- info->type_stack->type.classdef->pmisccount += 4;
-
- if (referencep)
- {
- unsigned int nindx;
-
- /* We need to output a record recording that this field is
- really of reference type. We put this on the refs field
- of classdef, so that it can be appended to the C++
- records after the class is defined. */
-
- nindx = info->name_indx;
- ++info->name_indx;
-
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->refs)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, 4)
- || ! ieee_write_asn (info, nindx, 'R')
- || ! ieee_write_asn (info, nindx, 3)
- || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- }
- }
-
- /* If the bitsize doesn't match the expected size, we need to output
- a bitfield type. */
- if (size == 0 || bitsize == 0 || bitsize == size * 8)
- offset = bitpos / 8;
- else
- {
- if (! ieee_define_type (info, 0, unsignedp,
- info->type_stack->type.localp)
- || ! ieee_write_number (info, 'g')
- || ! ieee_write_number (info, unsignedp ? 0 : 1)
- || ! ieee_write_number (info, bitsize)
- || ! ieee_write_number (info, indx))
- return false;
- indx = ieee_pop_type (info);
- offset = bitpos;
- }
-
- /* Switch to the struct we are building in order to output this
- field definition. */
- return (ieee_change_buffer (info, &info->type_stack->type.strdef)
- && ieee_write_id (info, name)
- && ieee_write_number (info, indx)
- && ieee_write_number (info, offset));
-}
-
-/* Finish up a struct type. */
-
-static boolean
-ieee_end_struct_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_buflist *pb;
-
- assert (info->type_stack != NULL
- && ! ieee_buffer_emptyp (&info->type_stack->type.strdef));
-
- /* If we were ignoring this struct definition because it was a
- duplicate defintion, just through away whatever bytes we have
- accumulated. Leave the type on the stack. */
- if (info->type_stack->type.ignorep)
- return true;
-
- /* If this is not a duplicate definition of this tag, then localp
- will be false, and we can put it in the global type block.
- FIXME: We should avoid outputting duplicate definitions which are
- the same. */
- if (! info->type_stack->type.localp)
- {
- /* Make sure we have started the global type block. */
- if (ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- return false;
- }
- pb = &info->global_types;
- }
- else
- {
- /* Make sure we have started the types block. */
- if (ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
- pb = &info->types;
- }
-
- /* Append the struct definition to the types. */
- if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef)
- || ! ieee_init_buffer (info, &info->type_stack->type.strdef))
- return false;
-
- /* Leave the struct on the type stack. */
-
- return true;
-}
-
-/* Start a class type. */
-
-static boolean
-ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
- boolean vptr;
- boolean ownvptr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- const char *vclass;
- struct ieee_buflist pmiscbuf;
- unsigned int indx;
- struct ieee_type_class *classdef;
-
- /* A C++ class is output as a C++ struct along with a set of pmisc
- records describing the class. */
-
- /* We need to have a name so that we can associate the struct and
- the class. */
- if (tag == NULL)
- {
- char *t;
-
- t = (char *) xmalloc (20);
- sprintf (t, "__anon%u", id);
- tag = t;
- }
-
- /* We can't write out the virtual table information until we have
- finished the class, because we don't know the virtual table size.
- We get the size from the largest voffset we see. */
- vclass = NULL;
- if (vptr && ! ownvptr)
- {
- vclass = info->type_stack->type.name;
- assert (vclass != NULL);
- /* We don't call ieee_pop_unused_type, since the class should
- get defined. */
- (void) ieee_pop_type (info);
- }
-
- if (! ieee_start_struct_type (p, tag, id, structp, size))
- return false;
-
- indx = info->name_indx;
- ++info->name_indx;
-
- /* We write out pmisc records into the classdef field. We will
- write out the pmisc start after we know the number of records we
- need. */
- if (! ieee_init_buffer (info, &pmiscbuf)
- || ! ieee_change_buffer (info, &pmiscbuf)
- || ! ieee_write_asn (info, indx, 'T')
- || ! ieee_write_asn (info, indx, structp ? 'o' : 'u')
- || ! ieee_write_atn65 (info, indx, tag))
- return false;
-
- classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef);
- memset (classdef, 0, sizeof *classdef);
-
- classdef->indx = indx;
- classdef->pmiscbuf = pmiscbuf;
- classdef->pmisccount = 3;
- classdef->vclass = vclass;
- classdef->ownvptr = ownvptr;
-
- info->type_stack->type.classdef = classdef;
-
- return true;
-}
-
-/* Add a static member to a class. */
-
-static boolean
-ieee_class_static_member (p, name, physname, visibility)
- PTR p;
- const char *name;
- const char *physname;
- enum debug_visibility visibility;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int flags;
- unsigned int nindx;
-
- /* We don't care about the type. Hopefully there will be a call to
- ieee_variable declaring the physical name and the type, since
- that is where an IEEE consumer must get the type. */
- ieee_pop_unused_type (info);
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL);
-
- flags = ieee_vis_to_flags (visibility);
- flags |= CXXFLAGS_STATIC;
-
- nindx = info->type_stack->type.classdef->indx;
-
- if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'd')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx, name)
- || ! ieee_write_atn65 (info, nindx, physname))
- return false;
- info->type_stack->type.classdef->pmisccount += 4;
-
- return true;
-}
-
-/* Add a base class to a class. */
-
-static boolean
-ieee_class_baseclass (p, bitpos, virtual, visibility)
- PTR p;
- bfd_vma bitpos;
- boolean virtual;
- enum debug_visibility visibility;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- const char *bname;
- boolean localp;
- unsigned int bindx;
- char *fname;
- unsigned int flags;
- unsigned int nindx;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.name != NULL
- && info->type_stack->next != NULL
- && info->type_stack->next->type.classdef != NULL
- && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
-
- bname = info->type_stack->type.name;
- localp = info->type_stack->type.localp;
- bindx = ieee_pop_type (info);
-
- /* We are currently defining both a struct and a class. We must
- write out a field definition in the struct which holds the base
- class. The stabs debugging reader will create a field named
- _vb$CLASS for a virtual base class, so we just use that. FIXME:
- we should not depend upon a detail of stabs debugging. */
- if (virtual)
- {
- fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$");
- sprintf (fname, "_vb$%s", bname);
- flags = BASEFLAGS_VIRTUAL;
- }
- else
- {
- if (localp)
- info->type_stack->type.localp = true;
-
- fname = (char *) xmalloc (strlen (bname) + sizeof "_b$");
- sprintf (fname, "_b$%s", bname);
-
- if (! ieee_change_buffer (info, &info->type_stack->type.strdef)
- || ! ieee_write_id (info, fname)
- || ! ieee_write_number (info, bindx)
- || ! ieee_write_number (info, bitpos / 8))
- return false;
- flags = 0;
- }
-
- if (visibility == DEBUG_VISIBILITY_PRIVATE)
- flags |= BASEFLAGS_PRIVATE;
-
- nindx = info->type_stack->type.classdef->indx;
-
- if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'b')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx, bname)
- || ! ieee_write_asn (info, nindx, 0)
- || ! ieee_write_atn65 (info, nindx, fname))
- return false;
- info->type_stack->type.classdef->pmisccount += 5;
-
- free (fname);
-
- return true;
-}
-
-/* Start building a method for a class. */
-
-static boolean
-ieee_class_start_method (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL
- && info->type_stack->type.classdef->method == NULL);
-
- info->type_stack->type.classdef->method = name;
-
- return true;
-}
-
-/* Define a new method variant, either static or not. */
-
-static boolean
-ieee_class_method_var (info, physname, visibility, staticp, constp,
- volatilep, voffset, context)
- struct ieee_handle *info;
- const char *physname;
- enum debug_visibility visibility;
- boolean staticp;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- boolean context;
-{
- unsigned int flags;
- unsigned int nindx;
- boolean virtual;
-
- /* We don't need the type of the method. An IEEE consumer which
- wants the type must track down the function by the physical name
- and get the type from that. */
- ieee_pop_unused_type (info);
-
- /* We don't use the context. FIXME: We probably ought to use it to
- adjust the voffset somehow, but I don't really know how. */
- if (context)
- ieee_pop_unused_type (info);
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL
- && info->type_stack->type.classdef->method != NULL);
-
- flags = ieee_vis_to_flags (visibility);
-
- /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR,
- CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */
-
- if (staticp)
- flags |= CXXFLAGS_STATIC;
- if (constp)
- flags |= CXXFLAGS_CONST;
- if (volatilep)
- flags |= CXXFLAGS_VOLATILE;
-
- nindx = info->type_stack->type.classdef->indx;
-
- virtual = context || voffset > 0;
-
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx,
- info->type_stack->type.classdef->method)
- || ! ieee_write_atn65 (info, nindx, physname))
- return false;
-
- if (virtual)
- {
- if (voffset > info->type_stack->type.classdef->voffset)
- info->type_stack->type.classdef->voffset = voffset;
- if (! ieee_write_asn (info, nindx, voffset))
- return false;
- ++info->type_stack->type.classdef->pmisccount;
- }
-
- if (! ieee_write_asn (info, nindx, 0))
- return false;
-
- info->type_stack->type.classdef->pmisccount += 5;
-
- return true;
-}
-
-/* Define a new method variant. */
-
-static boolean
-ieee_class_method_variant (p, physname, visibility, constp, volatilep,
- voffset, context)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- boolean context;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_class_method_var (info, physname, visibility, false, constp,
- volatilep, voffset, context);
-}
-
-/* Define a new static method variant. */
-
-static boolean
-ieee_class_static_method_variant (p, physname, visibility, constp, volatilep)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_class_method_var (info, physname, visibility, true, constp,
- volatilep, 0, false);
-}
-
-/* Finish up a method. */
-
-static boolean
-ieee_class_end_method (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL
- && info->type_stack->type.classdef->method != NULL);
-
- info->type_stack->type.classdef->method = NULL;
-
- return true;
-}
-
-/* Finish up a class. */
-
-static boolean
-ieee_end_class_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int nindx;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL);
-
- /* If we were ignoring this class definition because it was a
- duplicate definition, just through away whatever bytes we have
- accumulated. Leave the type on the stack. */
- if (info->type_stack->type.ignorep)
- return true;
-
- nindx = info->type_stack->type.classdef->indx;
-
- /* If we have a virtual table, we can write out the information now. */
- if (info->type_stack->type.classdef->vclass != NULL
- || info->type_stack->type.classdef->ownvptr)
- {
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'z')
- || ! ieee_write_atn65 (info, nindx, "")
- || ! ieee_write_asn (info, nindx,
- info->type_stack->type.classdef->voffset))
- return false;
- if (info->type_stack->type.classdef->ownvptr)
- {
- if (! ieee_write_atn65 (info, nindx, ""))
- return false;
- }
- else
- {
- if (! ieee_write_atn65 (info, nindx,
- info->type_stack->type.classdef->vclass))
- return false;
- }
- if (! ieee_write_asn (info, nindx, 0))
- return false;
- info->type_stack->type.classdef->pmisccount += 5;
- }
-
- /* Now that we know the number of pmisc records, we can write out
- the atn62 which starts the pmisc records, and append them to the
- C++ buffers. */
-
- if (! ieee_change_buffer (info, &info->cxx)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info,
- info->type_stack->type.classdef->pmisccount))
- return false;
-
- if (! ieee_append_buffer (info, &info->cxx,
- &info->type_stack->type.classdef->pmiscbuf))
- return false;
- if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs))
- {
- if (! ieee_append_buffer (info, &info->cxx,
- &info->type_stack->type.classdef->refs))
- return false;
- }
-
- return ieee_end_struct_type (p);
-}
-
-/* Push a previously seen typedef onto the type stack. */
-
-static boolean
-ieee_typedef_type (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt;
-
- h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false);
-
- /* h should never be NULL, since that would imply that the generic
- debugging code has asked for a typedef which it has not yet
- defined. */
- assert (h != NULL);
-
- /* We always use the most recently defined type for this name, which
- will be the first one on the list. */
-
- nt = h->types;
- if (! ieee_push_type (info, nt->type.indx, nt->type.size,
- nt->type.unsignedp, nt->type.localp))
- return false;
-
- /* Copy over any other type information we may have. */
- info->type_stack->type = nt->type;
-
- return true;
-}
-
-/* Push a tagged type onto the type stack. */
-
-static boolean
-ieee_tag_type (p, name, id, kind)
- PTR p;
- const char *name;
- unsigned int id;
- enum debug_type_kind kind;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- boolean copy;
- char ab[20];
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt;
-
- if (kind == DEBUG_KIND_ENUM)
- {
- struct ieee_defined_enum *e;
-
- if (name == NULL)
- abort ();
- for (e = info->enums; e != NULL; e = e->next)
- if (e->tag != NULL && strcmp (e->tag, name) == 0)
- return ieee_push_type (info, e->indx, 0, true, false);
-
- e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
-
- e->indx = info->type_indx;
- ++info->type_indx;
- e->tag = name;
- e->defined = false;
-
- e->next = info->enums;
- info->enums = e;
-
- return ieee_push_type (info, e->indx, 0, true, false);
- }
-
- localp = false;
-
- copy = false;
- if (name == NULL)
- {
- sprintf (ab, "__anon%u", id);
- name = ab;
- copy = true;
- }
-
- h = ieee_name_type_hash_lookup (&info->tags, name, true, copy);
- if (h == NULL)
- return false;
-
- for (nt = h->types; nt != NULL; nt = nt->next)
- {
- if (nt->id == id)
- {
- if (! ieee_push_type (info, nt->type.indx, nt->type.size,
- nt->type.unsignedp, nt->type.localp))
- return false;
- /* Copy over any other type information we may have. */
- info->type_stack->type = nt->type;
- return true;
- }
-
- if (! nt->type.localp)
- {
- /* This is a duplicate of a global type, so it must be
- local. */
- localp = true;
- }
- }
-
- nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
- memset (nt, 0, sizeof *nt);
-
- nt->id = id;
- nt->type.name = h->root.string;
- nt->type.indx = info->type_indx;
- nt->type.localp = localp;
- ++info->type_indx;
- nt->kind = kind;
-
- nt->next = h->types;
- h->types = nt;
-
- if (! ieee_push_type (info, nt->type.indx, 0, false, localp))
- return false;
-
- info->type_stack->type.name = h->root.string;
-
- return true;
-}
-
-/* Output a typedef. */
-
-static boolean
-ieee_typdef (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_write_type type;
- unsigned int indx;
- boolean found;
- boolean localp;
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt;
-
- type = info->type_stack->type;
- indx = type.indx;
-
- /* If this is a simple builtin type using a builtin name, we don't
- want to output the typedef itself. We also want to change the
- type index to correspond to the name being used. We recognize
- names used in stabs debugging output even if they don't exactly
- correspond to the names used for the IEEE builtin types. */
- found = false;
- if (indx <= (unsigned int) builtin_bcd_float)
- {
- switch ((enum builtin_types) indx)
- {
- default:
- break;
-
- case builtin_void:
- if (strcmp (name, "void") == 0)
- found = true;
- break;
-
- case builtin_signed_char:
- case builtin_char:
- if (strcmp (name, "signed char") == 0)
- {
- indx = (unsigned int) builtin_signed_char;
- found = true;
- }
- else if (strcmp (name, "char") == 0)
- {
- indx = (unsigned int) builtin_char;
- found = true;
- }
- break;
-
- case builtin_unsigned_char:
- if (strcmp (name, "unsigned char") == 0)
- found = true;
- break;
-
- case builtin_signed_short_int:
- case builtin_short:
- case builtin_short_int:
- case builtin_signed_short:
- if (strcmp (name, "signed short int") == 0)
- {
- indx = (unsigned int) builtin_signed_short_int;
- found = true;
- }
- else if (strcmp (name, "short") == 0)
- {
- indx = (unsigned int) builtin_short;
- found = true;
- }
- else if (strcmp (name, "short int") == 0)
- {
- indx = (unsigned int) builtin_short_int;
- found = true;
- }
- else if (strcmp (name, "signed short") == 0)
- {
- indx = (unsigned int) builtin_signed_short;
- found = true;
- }
- break;
-
- case builtin_unsigned_short_int:
- case builtin_unsigned_short:
- if (strcmp (name, "unsigned short int") == 0
- || strcmp (name, "short unsigned int") == 0)
- {
- indx = builtin_unsigned_short_int;
- found = true;
- }
- else if (strcmp (name, "unsigned short") == 0)
- {
- indx = builtin_unsigned_short;
- found = true;
- }
- break;
-
- case builtin_signed_long:
- case builtin_int: /* FIXME: Size depends upon architecture. */
- case builtin_long:
- if (strcmp (name, "signed long") == 0)
- {
- indx = builtin_signed_long;
- found = true;
- }
- else if (strcmp (name, "int") == 0)
- {
- indx = builtin_int;
- found = true;
- }
- else if (strcmp (name, "long") == 0
- || strcmp (name, "long int") == 0)
- {
- indx = builtin_long;
- found = true;
- }
- break;
-
- case builtin_unsigned_long:
- case builtin_unsigned: /* FIXME: Size depends upon architecture. */
- case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */
- if (strcmp (name, "unsigned long") == 0
- || strcmp (name, "long unsigned int") == 0)
- {
- indx = builtin_unsigned_long;
- found = true;
- }
- else if (strcmp (name, "unsigned") == 0)
- {
- indx = builtin_unsigned;
- found = true;
- }
- else if (strcmp (name, "unsigned int") == 0)
- {
- indx = builtin_unsigned_int;
- found = true;
- }
- break;
-
- case builtin_signed_long_long:
- if (strcmp (name, "signed long long") == 0
- || strcmp (name, "long long int") == 0)
- found = true;
- break;
-
- case builtin_unsigned_long_long:
- if (strcmp (name, "unsigned long long") == 0
- || strcmp (name, "long long unsigned int") == 0)
- found = true;
- break;
-
- case builtin_float:
- if (strcmp (name, "float") == 0)
- found = true;
- break;
-
- case builtin_double:
- if (strcmp (name, "double") == 0)
- found = true;
- break;
-
- case builtin_long_double:
- if (strcmp (name, "long double") == 0)
- found = true;
- break;
-
- case builtin_long_long_double:
- if (strcmp (name, "long long double") == 0)
- found = true;
- break;
- }
-
- if (found)
- type.indx = indx;
- }
-
- h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false);
- if (h == NULL)
- return false;
-
- /* See if we have already defined this type with this name. */
- localp = type.localp;
- for (nt = h->types; nt != NULL; nt = nt->next)
- {
- if (nt->id == indx)
- {
- /* If this is a global definition, then we don't need to
- do anything here. */
- if (! nt->type.localp)
- {
- ieee_pop_unused_type (info);
- return true;
- }
- }
- else
- {
- /* This is a duplicate definition, so make this one local. */
- localp = true;
- }
- }
-
- /* We need to add a new typedef for this type. */
-
- nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
- memset (nt, 0, sizeof *nt);
- nt->id = indx;
- nt->type = type;
- nt->type.name = name;
- nt->type.localp = localp;
- nt->kind = DEBUG_KIND_ILLEGAL;
-
- nt->next = h->types;
- h->types = nt;
-
- if (found)
- {
- /* This is one of the builtin typedefs, so we don't need to
- actually define it. */
- ieee_pop_unused_type (info);
- return true;
- }
-
- indx = ieee_pop_type (info);
-
- if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size,
- type.unsignedp, localp,
- (struct ieee_buflist *) NULL)
- || ! ieee_write_number (info, 'T')
- || ! ieee_write_number (info, indx))
- return false;
-
- /* Remove the type we just added to the type stack. This should not
- be ieee_pop_unused_type, since the type is used, we just don't
- need it now. */
- (void) ieee_pop_type (info);
-
- return true;
-}
-
-/* Output a tag for a type. We don't have to do anything here. */
-
-static boolean
-ieee_tag (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* This should not be ieee_pop_unused_type, since we want the type
- to be defined. */
- (void) ieee_pop_type (info);
- return true;
-}
-
-/* Output an integer constant. */
-
-static boolean
-ieee_int_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
- /* FIXME. */
- return true;
-}
-
-/* Output a floating point constant. */
-
-static boolean
-ieee_float_constant (p, name, val)
- PTR p;
- const char *name;
- double val;
-{
- /* FIXME. */
- return true;
-}
-
-/* Output a typed constant. */
-
-static boolean
-ieee_typed_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* FIXME. */
- ieee_pop_unused_type (info);
- return true;
-}
-
-/* Output a variable. */
-
-static boolean
-ieee_variable (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int name_indx;
- unsigned int size;
- boolean referencep;
- unsigned int type_indx;
- boolean asn;
- int refflag;
-
- size = info->type_stack->type.size;
- referencep = info->type_stack->type.referencep;
- type_indx = ieee_pop_type (info);
-
- assert (! ieee_buffer_emptyp (&info->vars));
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- name_indx = info->name_indx;
- ++info->name_indx;
-
- /* Write out an NN and an ATN record for this variable. */
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, name_indx)
- || ! ieee_write_id (info, name)
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, name_indx)
- || ! ieee_write_number (info, type_indx))
- return false;
- switch (kind)
- {
- default:
- abort ();
- return false;
- case DEBUG_GLOBAL:
- if (! ieee_write_number (info, 8)
- || ! ieee_add_range (info, false, val, val + size))
- return false;
- refflag = 0;
- asn = true;
- break;
- case DEBUG_STATIC:
- if (! ieee_write_number (info, 3)
- || ! ieee_add_range (info, false, val, val + size))
- return false;
- refflag = 1;
- asn = true;
- break;
- case DEBUG_LOCAL_STATIC:
- if (! ieee_write_number (info, 3)
- || ! ieee_add_range (info, false, val, val + size))
- return false;
- refflag = 2;
- asn = true;
- break;
- case DEBUG_LOCAL:
- if (! ieee_write_number (info, 1)
- || ! ieee_write_number (info, val))
- return false;
- refflag = 2;
- asn = false;
- break;
- case DEBUG_REGISTER:
- if (! ieee_write_number (info, 2)
- || ! ieee_write_number (info,
- ieee_genreg_to_regno (info->abfd, val)))
- return false;
- refflag = 2;
- asn = false;
- break;
- }
-
- if (asn)
- {
- if (! ieee_write_asn (info, name_indx, val))
- return false;
- }
-
- /* If this is really a reference type, then we just output it with
- pointer type, and must now output a C++ record indicating that it
- is really reference type. */
- if (referencep)
- {
- unsigned int nindx;
-
- nindx = info->name_indx;
- ++info->name_indx;
-
- /* If this is a global variable, we want to output the misc
- record in the C++ misc record block. Otherwise, we want to
- output it just after the variable definition, which is where
- the current buffer is. */
- if (refflag != 2)
- {
- if (! ieee_change_buffer (info, &info->cxx))
- return false;
- }
-
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, 3)
- || ! ieee_write_asn (info, nindx, 'R')
- || ! ieee_write_asn (info, nindx, refflag)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- }
-
- return true;
-}
-
-/* Start outputting information for a function. */
-
-static boolean
-ieee_start_function (p, name, global)
- PTR p;
- const char *name;
- boolean global;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean referencep;
- unsigned int retindx, typeindx;
-
- referencep = info->type_stack->type.referencep;
- retindx = ieee_pop_type (info);
-
- /* Besides recording a BB4 or BB6 block, we record the type of the
- function in the BB1 typedef block. We can't write out the full
- type until we have seen all the parameters, so we accumulate it
- in info->fntype and info->fnargs. */
- if (! ieee_buffer_emptyp (&info->fntype))
- {
- /* FIXME: This might happen someday if we support nested
- functions. */
- abort ();
- }
-
- info->fnname = name;
-
- /* An attribute of 0x40 means that the push mask is unknown. */
- if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true,
- &info->fntype)
- || ! ieee_write_number (info, 'x')
- || ! ieee_write_number (info, 0x40)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, retindx))
- return false;
-
- typeindx = ieee_pop_type (info);
-
- if (! ieee_init_buffer (info, &info->fnargs))
- return false;
- info->fnargcount = 0;
-
- /* If the function return value is actually a reference type, we
- must add a record indicating that. */
- if (referencep)
- {
- unsigned int nindx;
-
- nindx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->cxx)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, 3)
- || ! ieee_write_asn (info, nindx, 'R')
- || ! ieee_write_asn (info, nindx, global ? 0 : 1)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- }
-
- assert (! ieee_buffer_emptyp (&info->vars));
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- /* The address is written out as the first block. */
-
- ++info->block_depth;
-
- return (ieee_write_byte (info, (int) ieee_bb_record_enum)
- && ieee_write_byte (info, global ? 4 : 6)
- && ieee_write_number (info, 0)
- && ieee_write_id (info, name)
- && ieee_write_number (info, 0)
- && ieee_write_number (info, typeindx));
-}
-
-/* Add a function parameter. This will normally be called before the
- first block, so we postpone them until we see the block. */
-
-static boolean
-ieee_function_parameter (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_parm_kind kind;
- bfd_vma val;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_pending_parm *m, **pm;
-
- assert (info->block_depth == 1);
-
- m = (struct ieee_pending_parm *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->next = NULL;
- m->name = name;
- m->referencep = info->type_stack->type.referencep;
- m->type = ieee_pop_type (info);
- m->kind = kind;
- m->val = val;
-
- for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next)
- ;
- *pm = m;
-
- /* Add the type to the fnargs list. */
- if (! ieee_change_buffer (info, &info->fnargs)
- || ! ieee_write_number (info, m->type))
- return false;
- ++info->fnargcount;
-
- return true;
-}
-
-/* Output pending function parameters. */
-
-static boolean
-ieee_output_pending_parms (info)
- struct ieee_handle *info;
-{
- struct ieee_pending_parm *m;
- unsigned int refcount;
-
- refcount = 0;
- for (m = info->pending_parms; m != NULL; m = m->next)
- {
- enum debug_var_kind vkind;
-
- switch (m->kind)
- {
- default:
- abort ();
- return false;
- case DEBUG_PARM_STACK:
- case DEBUG_PARM_REFERENCE:
- vkind = DEBUG_LOCAL;
- break;
- case DEBUG_PARM_REG:
- case DEBUG_PARM_REF_REG:
- vkind = DEBUG_REGISTER;
- break;
- }
-
- if (! ieee_push_type (info, m->type, 0, false, false))
- return false;
- info->type_stack->type.referencep = m->referencep;
- if (m->referencep)
- ++refcount;
- if (! ieee_variable ((PTR) info, m->name, vkind, m->val))
- return false;
- }
-
- /* If there are any reference parameters, we need to output a
- miscellaneous record indicating them. */
- if (refcount > 0)
- {
- unsigned int nindx, varindx;
-
- /* FIXME: The MRI compiler outputs the demangled function name
- here, but we are outputting the mangled name. */
- nindx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, refcount + 3)
- || ! ieee_write_asn (info, nindx, 'B')
- || ! ieee_write_atn65 (info, nindx, info->fnname)
- || ! ieee_write_asn (info, nindx, 0))
- return false;
- for (m = info->pending_parms, varindx = 1;
- m != NULL;
- m = m->next, varindx++)
- {
- if (m->referencep)
- {
- if (! ieee_write_asn (info, nindx, varindx))
- return false;
- }
- }
- }
-
- m = info->pending_parms;
- while (m != NULL)
- {
- struct ieee_pending_parm *next;
-
- next = m->next;
- free (m);
- m = next;
- }
-
- info->pending_parms = NULL;
-
- return true;
-}
-
-/* Start a block. If this is the first block, we output the address
- to finish the BB4 or BB6, and then output the function parameters. */
-
-static boolean
-ieee_start_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- if (info->block_depth == 1)
- {
- if (! ieee_write_number (info, addr)
- || ! ieee_output_pending_parms (info))
- return false;
- }
- else
- {
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 6)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, addr))
- return false;
- }
-
- if (! ieee_start_range (info, addr))
- return false;
-
- ++info->block_depth;
-
- return true;
-}
-
-/* End a block. */
-
-static boolean
-ieee_end_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* The address we are given is the end of the block, but IEEE seems
- to want to the address of the last byte in the block, so we
- subtract one. */
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, addr - 1))
- return false;
-
- if (! ieee_end_range (info, addr))
- return false;
-
- --info->block_depth;
-
- if (addr > info->highaddr)
- info->highaddr = addr;
-
- return true;
-}
-
-/* End a function. */
-
-static boolean
-ieee_end_function (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->block_depth == 1);
-
- --info->block_depth;
-
- /* Now we can finish up fntype, and add it to the typdef section.
- At this point, fntype is the 'x' type up to the argument count,
- and fnargs is the argument types. We must add the argument
- count, and we must add the level. FIXME: We don't record varargs
- functions correctly. In fact, stabs debugging does not give us
- enough information to do so. */
- if (! ieee_change_buffer (info, &info->fntype)
- || ! ieee_write_number (info, info->fnargcount)
- || ! ieee_change_buffer (info, &info->fnargs)
- || ! ieee_write_number (info, 0))
- return false;
-
- /* Make sure the typdef block has been started. */
- if (ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
-
- if (! ieee_append_buffer (info, &info->types, &info->fntype)
- || ! ieee_append_buffer (info, &info->types, &info->fnargs))
- return false;
-
- info->fnname = NULL;
- if (! ieee_init_buffer (info, &info->fntype)
- || ! ieee_init_buffer (info, &info->fnargs))
- return false;
- info->fnargcount = 0;
-
- return true;
-}
-
-/* Record line number information. */
-
-static boolean
-ieee_lineno (p, filename, lineno, addr)
- PTR p;
- const char *filename;
- unsigned long lineno;
- bfd_vma addr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->filename != NULL);
-
- /* The HP simulator seems to get confused when more than one line is
- listed for the same address, at least if they are in different
- files. We handle this by always listing the last line for a
- given address, since that seems to be the one that gdb uses. */
- if (info->pending_lineno_filename != NULL
- && addr != info->pending_lineno_addr)
- {
- /* Make sure we have a line number block. */
- if (! ieee_buffer_emptyp (&info->linenos))
- {
- if (! ieee_change_buffer (info, &info->linenos))
- return false;
- }
- else
- {
- info->lineno_name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->linenos)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 5)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->filename)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_id (info, ""))
- return false;
- info->lineno_filename = info->filename;
- }
-
- if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0)
- {
- if (strcmp (info->filename, info->lineno_filename) != 0)
- {
- /* We were not in the main file. Close the block for the
- included file. */
- if (! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- if (strcmp (info->filename, info->pending_lineno_filename) == 0)
- {
- /* We need a new NN record, and we aren't about to
- output one. */
- info->lineno_name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_id (info, ""))
- return false;
- }
- }
- if (strcmp (info->filename, info->pending_lineno_filename) != 0)
- {
- /* We are not changing to the main file. Open a block for
- the new included file. */
- info->lineno_name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 5)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->pending_lineno_filename)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_id (info, ""))
- return false;
- }
- info->lineno_filename = info->pending_lineno_filename;
- }
-
- if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 7)
- || ! ieee_write_number (info, info->pending_lineno)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_asn (info, info->lineno_name_indx,
- info->pending_lineno_addr))
- return false;
- }
-
- info->pending_lineno_filename = filename;
- info->pending_lineno = lineno;
- info->pending_lineno_addr = addr;
-
- return true;
-}
diff --git a/pstack/ieee.h b/pstack/ieee.h
deleted file mode 100644
index 56634b2819a..00000000000
--- a/pstack/ieee.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file
- Contributed by Cygnus Support. */
-
-#define N_W_VARIABLES 8
-#define Module_Beginning 0xe0
-
-typedef struct ieee_module {
- char *processor;
- char *module_name;
-} ieee_module_begin_type;
-
-#define Address_Descriptor 0xec
-typedef struct ieee_address {
-bfd_vma number_of_bits_mau;
- bfd_vma number_of_maus_in_address;
-
- unsigned char byte_order;
-#define IEEE_LITTLE 0xcc
-#define IEEE_BIG 0xcd
-} ieee_address_descriptor_type;
-
-typedef union ieee_w_variable {
- file_ptr offset[N_W_VARIABLES];
- struct {
- file_ptr extension_record;
- file_ptr environmental_record;
- file_ptr section_part;
- file_ptr external_part;
- file_ptr debug_information_part;
- file_ptr data_part;
- file_ptr trailer_part;
- file_ptr me_record;
- } r;
-} ieee_w_variable_type;
-
-
-
-
-
-typedef enum ieee_record
-{
- ieee_number_start_enum = 0x00,
- ieee_number_end_enum=0x7f,
- ieee_number_repeat_start_enum = 0x80,
- ieee_number_repeat_end_enum = 0x88,
- ieee_number_repeat_4_enum = 0x84,
- ieee_number_repeat_3_enum = 0x83,
- ieee_number_repeat_2_enum = 0x82,
- ieee_number_repeat_1_enum = 0x81,
- ieee_module_beginning_enum = 0xe0,
- ieee_module_end_enum = 0xe1,
- ieee_extension_length_1_enum = 0xde,
- ieee_extension_length_2_enum = 0xdf,
- ieee_section_type_enum = 0xe6,
- ieee_section_alignment_enum = 0xe7,
- ieee_external_symbol_enum = 0xe8,
- ieee_comma = 0x90,
- ieee_external_reference_enum = 0xe9,
- ieee_set_current_section_enum = 0xe5,
- ieee_address_descriptor_enum = 0xec,
- ieee_load_constant_bytes_enum = 0xed,
- ieee_load_with_relocation_enum = 0xe4,
-
- ieee_variable_A_enum = 0xc1,
- ieee_variable_B_enum = 0xc2,
- ieee_variable_C_enum = 0xc3,
- ieee_variable_D_enum = 0xc4,
- ieee_variable_E_enum = 0xc5,
- ieee_variable_F_enum = 0xc6,
- ieee_variable_G_enum = 0xc7,
- ieee_variable_H_enum = 0xc8,
- ieee_variable_I_enum = 0xc9,
- ieee_variable_J_enum = 0xca,
- ieee_variable_K_enum = 0xcb,
- ieee_variable_L_enum = 0xcc,
- ieee_variable_M_enum = 0xcd,
- ieee_variable_N_enum = 0xce,
- ieee_variable_O_enum = 0xcf,
- ieee_variable_P_enum = 0xd0,
- ieee_variable_Q_enum = 0xd1,
- ieee_variable_R_enum = 0xd2,
- ieee_variable_S_enum = 0xd3,
- ieee_variable_T_enum = 0xd4,
- ieee_variable_U_enum = 0xd5,
- ieee_variable_V_enum = 0xd6,
- ieee_variable_W_enum = 0xd7,
- ieee_variable_X_enum = 0xd8,
- ieee_variable_Y_enum = 0xd9,
- ieee_variable_Z_enum = 0xda,
- ieee_function_plus_enum = 0xa5,
- ieee_function_minus_enum = 0xa6,
- ieee_function_signed_open_b_enum = 0xba,
- ieee_function_signed_close_b_enum = 0xbb,
-
- ieee_function_unsigned_open_b_enum = 0xbc,
- ieee_function_unsigned_close_b_enum = 0xbd,
-
- ieee_function_either_open_b_enum = 0xbe,
- ieee_function_either_close_b_enum = 0xbf,
- ieee_record_seperator_enum = 0xdb,
-
- ieee_e2_first_byte_enum = 0xe2,
- ieee_section_size_enum = 0xe2d3,
- ieee_physical_region_size_enum = 0xe2c1,
- ieee_region_base_address_enum = 0xe2c2,
- ieee_mau_size_enum = 0xe2c6,
- ieee_m_value_enum = 0xe2cd,
- ieee_section_base_address_enum = 0xe2cc,
- ieee_asn_record_enum = 0xe2ce,
- ieee_section_offset_enum = 0xe2d2,
- ieee_value_starting_address_enum = 0xe2c7,
- ieee_assign_value_to_variable_enum = 0xe2d7,
- ieee_set_current_pc_enum = 0xe2d0,
- ieee_value_record_enum = 0xe2c9,
- ieee_nn_record = 0xf0,
- ieee_at_record_enum = 0xf1,
- ieee_ty_record_enum = 0xf2,
- ieee_attribute_record_enum = 0xf1c9,
- ieee_atn_record_enum = 0xf1ce,
- ieee_external_reference_info_record_enum = 0xf1d8,
- ieee_weak_external_reference_enum= 0xf4,
- ieee_repeat_data_enum = 0xf7,
- ieee_bb_record_enum = 0xf8,
- ieee_be_record_enum = 0xf9
-} ieee_record_enum_type;
-
-
-typedef struct ieee_section {
- unsigned int section_index;
- unsigned int section_type;
- char *section_name;
- unsigned int parent_section_index;
- unsigned int sibling_section_index;
- unsigned int context_index;
-} ieee_section_type;
-#define IEEE_REFERENCE_BASE 11
-#define IEEE_PUBLIC_BASE 32
-#define IEEE_SECTION_NUMBER_BASE 1
diff --git a/pstack/libiberty.h b/pstack/libiberty.h
deleted file mode 100644
index ca0043d31c6..00000000000
--- a/pstack/libiberty.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Function declarations for libiberty.
- Written by Cygnus Support, 1994.
-
- The libiberty library provides a number of functions which are
- missing on some operating systems. We do not declare those here,
- to avoid conflicts with the system header files on operating
- systems that do support those functions. In this file we only
- declare those functions which are specific to libiberty. */
-
-#ifndef LIBIBERTY_H
-#define LIBIBERTY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "ansidecl.h"
-
-/* Build an argument vector from a string. Allocates memory using
- malloc. Use freeargv to free the vector. */
-
-extern char **buildargv PARAMS ((char *));
-
-/* Free a vector returned by buildargv. */
-
-extern void freeargv PARAMS ((char **));
-
-/* Duplicate an argument vector. Allocates memory using malloc. Use
- freeargv to free the vector. */
-
-extern char **dupargv PARAMS ((char **));
-
-
-/* Return the last component of a path name. Note that we can't use a
- prototype here because the parameter is declared inconsistently
- across different systems, sometimes as "char *" and sometimes as
- "const char *" */
-
-#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__)
-extern char *basename PARAMS ((const char *));
-#else
-extern char *basename ();
-#endif
-
-/* Concatenate an arbitrary number of strings, up to (char *) NULL.
- Allocates memory using xmalloc. */
-
-extern char *concat PARAMS ((const char *, ...));
-
-/* Check whether two file descriptors refer to the same file. */
-
-extern int fdmatch PARAMS ((int fd1, int fd2));
-
-/* Get the amount of time the process has run, in microseconds. */
-
-extern long get_run_time PARAMS ((void));
-
-/* Choose a temporary directory to use for scratch files. */
-
-extern char *choose_temp_base PARAMS ((void));
-
-/* Allocate memory filled with spaces. Allocates using malloc. */
-
-extern const char *spaces PARAMS ((int count));
-
-/* Return the maximum error number for which strerror will return a
- string. */
-
-extern int errno_max PARAMS ((void));
-
-/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
- "EINVAL"). */
-
-extern const char *strerrno PARAMS ((int));
-
-/* Given the name of an errno value, return the value. */
-
-extern int strtoerrno PARAMS ((const char *));
-
-/* ANSI's strerror(), but more robust. */
-
-extern char *xstrerror PARAMS ((int));
-
-/* Return the maximum signal number for which strsignal will return a
- string. */
-
-extern int signo_max PARAMS ((void));
-
-/* Return a signal message string for a signal number
- (e.g., strsignal (SIGHUP) returns something like "Hangup"). */
-/* This is commented out as it can conflict with one in system headers.
- We still document its existence though. */
-
-/*extern const char *strsignal PARAMS ((int));*/
-
-/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
- "SIGHUP"). */
-
-extern const char *strsigno PARAMS ((int));
-
-/* Given the name of a signal, return its number. */
-
-extern int strtosigno PARAMS ((const char *));
-
-/* Register a function to be run by xexit. Returns 0 on success. */
-
-extern int xatexit PARAMS ((void (*fn) (void)));
-
-/* Exit, calling all the functions registered with xatexit. */
-
-#ifndef __GNUC__
-extern void xexit PARAMS ((int status));
-#else
-void xexit PARAMS ((int status)) __attribute__ ((noreturn));
-#endif
-
-/* Set the program name used by xmalloc. */
-
-extern void xmalloc_set_program_name PARAMS ((const char *));
-
-/* Allocate memory without fail. If malloc fails, this will print a
- message to stderr (using the name set by xmalloc_set_program_name,
- if any) and then call xexit. */
-
-#ifdef ANSI_PROTOTYPES
-/* Get a definition for size_t. */
-#include <stddef.h>
-#endif
-extern PTR xmalloc PARAMS ((size_t));
-
-/* Reallocate memory without fail. This works like xmalloc.
-
- FIXME: We do not declare the parameter types for the same reason as
- xmalloc. */
-
-extern PTR xrealloc PARAMS ((PTR, size_t));
-
-/* Allocate memory without fail and set it to zero. This works like
- xmalloc. */
-
-extern PTR xcalloc PARAMS ((size_t, size_t));
-
-/* Copy a string into a memory buffer without fail. */
-
-extern char *xstrdup PARAMS ((const char *));
-
-/* hex character manipulation routines */
-
-#define _hex_array_size 256
-#define _hex_bad 99
-extern char _hex_value[_hex_array_size];
-extern void hex_init PARAMS ((void));
-#define hex_p(c) (hex_value (c) != _hex_bad)
-/* If you change this, note well: Some code relies on side effects in
- the argument being performed exactly once. */
-#define hex_value(c) (_hex_value[(unsigned char) (c)])
-
-/* Definitions used by the pexecute routine. */
-
-#define PEXECUTE_FIRST 1
-#define PEXECUTE_LAST 2
-#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
-#define PEXECUTE_SEARCH 4
-#define PEXECUTE_VERBOSE 8
-
-/* Execute a program. */
-
-extern int pexecute PARAMS ((const char *, char * const *, const char *,
- const char *, char **, char **, int));
-
-/* Wait for pexecute to finish. */
-
-extern int pwait PARAMS ((int, int *, int));
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* ! defined (LIBIBERTY_H) */
diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c
deleted file mode 100644
index 8624bd21782..00000000000
--- a/pstack/linuxthreads.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $Header$ */
-
-/*
- * LinuxThreads specific stuff.
- */
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <limits.h> /* PTHREAD_THREADS_MAX */
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sched.h>
-
-#include "linuxthreads.h"
-
-#define AT_INT(intval) *((int32_t*)(intval))
-
-/*
- * Internal LinuxThreads variables.
- * Official interface exposed to GDB.
- */
-#if 1
-extern volatile int __pthread_threads_debug;
-extern volatile char __pthread_handles;
-extern char __pthread_initial_thread;
-/*extern volatile Elf32_Sym* __pthread_manager_thread;*/
-extern const int __pthread_sizeof_handle;
-extern const int __pthread_offsetof_descr;
-extern const int __pthread_offsetof_pid;
-extern volatile int __pthread_handles_num;
-#endif /* 0 */
-
-/*
- * Notify others.
- */
-int
-linuxthreads_notify_others( const int signotify)
-{
- const pid_t mypid = getpid();
- //const pthread_t mytid = pthread_self();
- int i;
- int threadcount = 0;
- int threads[PTHREAD_THREADS_MAX];
- int pid;
-
- TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num));
- if (__pthread_handles_num==2) {
- /* no threads beside the initial thread */
- return 0;
- }
- /*assert(maxthreads>=3);
- assert(maxthreads>=__pthread_handles_num+2);*/
-
- // take the initial thread with us
- pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid);
- if (pid!=mypid && pid!=0)
- threads[threadcount++] = pid;
- // don't know why, but always handles[0]==handles[1]
- for (i=1; i<__pthread_handles_num; ++i) {
- const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr);
- assert(descr!=0);
- pid = AT_INT(descr+__pthread_offsetof_pid);
- if (pid!=mypid && pid!=0)
- threads[threadcount++] = pid;
- }
- /* TRACE_FPRINTF((stderr, "Stopping threads...")); */
- //for (i=0; i<threadcount; ++i) {
- // /* TRACE_FPRINTF((stderr, "%d ", threads[i])); */
- // fflush(stdout);
- // kill(threads[i], SIGSTOP); /* Tell thread to stop */
- //}
- /* TRACE_FPRINTF((stderr, " done!\n")); */
- for (i=0; i<threadcount; ++i) {
- TRACE_FPRINTF((stderr, "--- NOTIFYING %d\n", threads[i]));
- kill(threads[i], signotify); /* Tell to print stack trace */
- /* TRACE_FPRINTF((stderr, "--- WAITING FOR %d\n", threads[i])); */
- /*pause(); Wait for confirmation. */
- }
- for (i=0; i<threadcount; ++i)
- sched_yield();
- for (i=0; i<threadcount; ++i) {
- TRACE_FPRINTF((stderr, "--- KILLING %d\n", threads[i]));
- kill(threads[i], SIGKILL); /* Tell thread die :) */
- }
- return __pthread_handles_num;
-}
-
diff --git a/pstack/linuxthreads.h b/pstack/linuxthreads.h
deleted file mode 100644
index f5eb0f652d8..00000000000
--- a/pstack/linuxthreads.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Header$ */
-
-/*
- * LinuxThreads specific stuff.
- */
-
-#ifndef pstack_linuxthreads_h_
-#define pstack_linuxthreads_h_
-
-#include <pthread.h>
-#include "pstacktrace.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Tell other threads to dump stacks...
- */
-int
-linuxthreads_notify_others( const int signotify);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* pstack_linuxthreads_h_ */
-
diff --git a/pstack/pstack.c b/pstack/pstack.c
deleted file mode 100644
index 4cdd80d68b5..00000000000
--- a/pstack/pstack.c
+++ /dev/null
@@ -1,2746 +0,0 @@
-/*
- pstack.c -- asynchronous stack trace of a running process
- Copyright (c) 1999 Ross Thompson
- Author: Ross Thompson <ross@whatsis.com>
- Critical bug fix: Tim Waugh
-*/
-
-/*
- This file is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-/* RESTRICTIONS:
-
- pstack currently works only on Linux, only on an x86 machine running
- 32 bit ELF binaries (64 bit not supported). Also, for symbolic
- information, you need to use a GNU compiler to generate your
- program, and you can't strip symbols from the binaries. For thread
- information to be dumped, you have to use the debug-aware version
- of libpthread.so. (To check, run 'nm' on your libpthread.so, and
- make sure that the symbol "__pthread_threads_debug" is defined.)
-
- The details of pulling stuff out of ELF files and running through
- program images is very platform specific, and I don't want to
- try to support modes or machine types I can't test in or on.
- If someone wants to generalize this to other architectures, I would
- be happy to help and coordinate the activity. Please send me whatever
- changes you make to support these machines, so that I can own the
- central font of all truth (at least as regards this program).
-
- Thanks
-*/
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/ptrace.h>
-#include <asm/ptrace.h>
-
-#include <assert.h>
-#include <fcntl.h>
-#include <link.h>
-#include <malloc.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-#include <pthread.h>
-#include <limits.h> /* PTHREAD_THREADS_MAX */
-
-
-#include <bfd.h>
-
-#include "libiberty.h"
-
-#include "pstack.h" /* just one function */
-#include "budbg.h" /* binutils stuff related to debugging symbols. */
-#include "bucomm.h" /* some common stuff */
-#include "debug.h" /* and more binutils stuff... */
-#include "budbg.h"
-#include "linuxthreads.h" /* LinuxThreads specific stuff... */
-
-
-/*
- * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)(
- * due to malloc's unavalaibility.
- */
-int
-fdprintf( int fd,
- const char* fmt,...)
-{
- char xbuf[2048];// FIXME: enough?
- va_list ap;
- int r;
- if (fd<0)
- return -1;
- va_start(ap, fmt);
- r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
- va_end(ap);
- return write(fd, xbuf, r);
-}
-
-int
-fdputc( char c,
- int fd)
-{
- if (fd<0)
- return -1;
- return write(fd, &c, sizeof(c));
-}
-
-int
-fdputs( const char* s,
- int fd)
-{
- if (fd<0)
- return -1;
- return write(fd, s, strlen(s));
-}
-
-/*
- * Use this function to open log file.
- * Flags: truncate on opening.
- */
-static const char* path_format = "stack-trace-on-segv-%d.txt";
-static int
-open_log_file( const pthread_t tid,
- const pid_t pid)
-{
- char fname[PATH_MAX];
- int r;
- snprintf(fname, sizeof(fname), path_format, tid, pid);
- r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
- S_IRUSR|S_IWUSR);
- if (r<0)
- perror("open");
- return r;
-}
-/*
- * Add additional debugging information for functions.
- */
-
-/*
- * Lineno
- */
-typedef struct {
- int lineno;
- bfd_vma addr;
-} debug_lineno_t;
-
-/*
- * Block - a {} pair.
- */
-typedef struct debug_block_st {
- bfd_vma begin_addr; /* where did it start */
- bfd_vma end_addr; /* where did it end */
- struct debug_block_st* parent;
- struct debug_block_st* childs;
- int childs_count;
-} debug_block_t;
-
-/*
- * Function parameter.
- */
-typedef struct {
- bfd_vma offset; /* Offset in the stack */
- const char* name; /* And name. */
-} debug_parameter_t;
-
-/*
- * Extra information about functions.
- */
-typedef struct {
- asymbol* symbol; /* mangled function name, addr */
- debug_lineno_t* lines;
- int lines_count;
- int max_lines_count;
- const char* name;
- const char* filename;/* a file name it occured in... */
- debug_block_t* block; /* each function has a block, or not, you know */
- debug_parameter_t* argv; /* argument types. */
- int argc;
- int max_argc;
-} debug_function_t;
-
-/* This is the structure we use as a handle for these routines. */
-struct pr_handle
-{
- /* File to print information to. */
- FILE *f;
- /* Current indentation level. */
- unsigned int indent;
- /* Type stack. */
- struct pr_stack *stack;
- /* Parameter number we are about to output. */
- int parameter;
- debug_block_t* block; /* current block */
- debug_function_t* function; /* current function */
- debug_function_t* functions; /* all functions */
- int functions_size; /* current size */
- int functions_maxsize; /* maximum size */
-};
-
-/* The type stack. */
-
-struct pr_stack
-{
- /* Next element on the stack. */
- struct pr_stack *next;
- /* This element. */
- char *type;
- /* Current visibility of fields if this is a class. */
- enum debug_visibility visibility;
- /* Name of the current method we are handling. */
- const char *method;
-};
-
-static void indent PARAMS ((struct pr_handle *));
-static boolean push_type PARAMS ((struct pr_handle *, const char *));
-static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
-static boolean append_type PARAMS ((struct pr_handle *, const char *));
-static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
-static boolean indent_type PARAMS ((struct pr_handle *));
-static char *pop_type PARAMS ((struct pr_handle *));
-static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
-static boolean pr_fix_visibility
- PARAMS ((struct pr_handle *, enum debug_visibility));
-
-static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
-static boolean pr_start_source PARAMS ((PTR, const char *));
-static boolean pr_empty_type PARAMS ((PTR));
-static boolean pr_void_type PARAMS ((PTR));
-static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
-static boolean pr_float_type PARAMS ((PTR, unsigned int));
-static boolean pr_complex_type PARAMS ((PTR, unsigned int));
-static boolean pr_bool_type PARAMS ((PTR, unsigned int));
-static boolean pr_enum_type
- PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
-static boolean pr_pointer_type PARAMS ((PTR));
-static boolean pr_function_type PARAMS ((PTR, int, boolean));
-static boolean pr_reference_type PARAMS ((PTR));
-static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
-static boolean pr_array_type
- PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
-static boolean pr_set_type PARAMS ((PTR, boolean));
-static boolean pr_offset_type PARAMS ((PTR));
-static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
-static boolean pr_const_type PARAMS ((PTR));
-static boolean pr_volatile_type PARAMS ((PTR));
-static boolean pr_start_struct_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
-static boolean pr_struct_field
- PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
-static boolean pr_end_struct_type PARAMS ((PTR));
-static boolean pr_start_class_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
- boolean));
-static boolean pr_class_static_member
- PARAMS ((PTR, const char *, const char *, enum debug_visibility));
-static boolean pr_class_baseclass
- PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
-static boolean pr_class_start_method PARAMS ((PTR, const char *));
-static boolean pr_class_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
- bfd_vma, boolean));
-static boolean pr_class_static_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
-static boolean pr_class_end_method PARAMS ((PTR));
-static boolean pr_end_class_type PARAMS ((PTR));
-static boolean pr_typedef_type PARAMS ((PTR, const char *));
-static boolean pr_tag_type
- PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
-static boolean pr_typdef PARAMS ((PTR, const char *));
-static boolean pr_tag PARAMS ((PTR, const char *));
-static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean pr_float_constant PARAMS ((PTR, const char *, double));
-static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean pr_variable
- PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
-static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
-static boolean pr_function_parameter
- PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
-static boolean pr_start_block PARAMS ((PTR, bfd_vma));
-static boolean pr_end_block PARAMS ((PTR, bfd_vma));
-static boolean pr_end_function PARAMS ((PTR));
-static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
-
-static const struct debug_write_fns pr_fns =
-{
- pr_start_compilation_unit,
- pr_start_source,
- pr_empty_type,
- pr_void_type,
- pr_int_type,
- pr_float_type,
- pr_complex_type,
- pr_bool_type,
- pr_enum_type,
- pr_pointer_type,
- pr_function_type,
- pr_reference_type,
- pr_range_type,
- pr_array_type,
- pr_set_type,
- pr_offset_type,
- pr_method_type,
- pr_const_type,
- pr_volatile_type,
- pr_start_struct_type,
- pr_struct_field,
- pr_end_struct_type,
- pr_start_class_type,
- pr_class_static_member,
- pr_class_baseclass,
- pr_class_start_method,
- pr_class_method_variant,
- pr_class_static_method_variant,
- pr_class_end_method,
- pr_end_class_type,
- pr_typedef_type,
- pr_tag_type,
- pr_typdef,
- pr_tag,
- pr_int_constant,
- pr_float_constant,
- pr_typed_constant,
- pr_variable,
- pr_start_function,
- pr_function_parameter,
- pr_start_block,
- pr_end_block,
- pr_end_function,
- pr_lineno
-};
-
-
-/* Indent to the current indentation level. */
-
-static void
-indent (info)
- struct pr_handle *info;
-{
- unsigned int i;
-
- for (i = 0; i < info->indent; i++)
- TRACE_PUTC ((' ', info->f));
-}
-
-/* Push a type on the type stack. */
-
-static boolean
-push_type (info, type)
- struct pr_handle *info;
- const char *type;
-{
- struct pr_stack *n;
-
- if (type == NULL)
- return false;
-
- n = (struct pr_stack *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->type = xstrdup (type);
- n->visibility = DEBUG_VISIBILITY_IGNORE;
- n->method = NULL;
- n->next = info->stack;
- info->stack = n;
-
- return true;
-}
-
-/* Prepend a string onto the type on the top of the type stack. */
-
-static boolean
-prepend_type (info, s)
- struct pr_handle *info;
- const char *s;
-{
- char *n;
-
- assert (info->stack != NULL);
-
- n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
- sprintf (n, "%s%s", s, info->stack->type);
- free (info->stack->type);
- info->stack->type = n;
-
- return true;
-}
-
-/* Append a string to the type on the top of the type stack. */
-
-static boolean
-append_type (info, s)
- struct pr_handle *info;
- const char *s;
-{
- unsigned int len;
-
- if (s == NULL)
- return false;
-
- assert (info->stack != NULL);
-
- len = strlen (info->stack->type);
- info->stack->type = (char *) xrealloc (info->stack->type,
- len + strlen (s) + 1);
- strcpy (info->stack->type + len, s);
-
- return true;
-}
-
-/* We use an underscore to indicate where the name should go in a type
- string. This function substitutes a string for the underscore. If
- there is no underscore, the name follows the type. */
-
-static boolean
-substitute_type (info, s)
- struct pr_handle *info;
- const char *s;
-{
- char *u;
-
- assert (info->stack != NULL);
-
- u = strchr (info->stack->type, '|');
- if (u != NULL)
- {
- char *n;
-
- n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
-
- memcpy (n, info->stack->type, u - info->stack->type);
- strcpy (n + (u - info->stack->type), s);
- strcat (n, u + 1);
-
- free (info->stack->type);
- info->stack->type = n;
-
- return true;
- }
-
- if (strchr (s, '|') != NULL
- && (strchr (info->stack->type, '{') != NULL
- || strchr (info->stack->type, '(') != NULL))
- {
- if (! prepend_type (info, "(")
- || ! append_type (info, ")"))
- return false;
- }
-
- if (*s == '\0')
- return true;
-
- return (append_type (info, " ")
- && append_type (info, s));
-}
-
-/* Indent the type at the top of the stack by appending spaces. */
-
-static boolean
-indent_type (info)
- struct pr_handle *info;
-{
- unsigned int i;
-
- for (i = 0; i < info->indent; i++)
- {
- if (! append_type (info, " "))
- return false;
- }
-
- return true;
-}
-
-/* Pop a type from the type stack. */
-
-static char *
-pop_type (info)
- struct pr_handle *info;
-{
- struct pr_stack *o;
- char *ret;
-
- assert (info->stack != NULL);
-
- o = info->stack;
- info->stack = o->next;
- ret = o->type;
- free (o);
-
- return ret;
-}
-
-/* Print a VMA value into a string. */
-
-static void
-print_vma (vma, buf, unsignedp, hexp)
- bfd_vma vma;
- char *buf;
- boolean unsignedp;
- boolean hexp;
-{
- if (sizeof (vma) <= sizeof (unsigned long))
- {
- if (hexp)
- sprintf (buf, "0x%lx", (unsigned long) vma);
- else if (unsignedp)
- sprintf (buf, "%lu", (unsigned long) vma);
- else
- sprintf (buf, "%ld", (long) vma);
- }
- else
- {
- buf[0] = '0';
- buf[1] = 'x';
- sprintf_vma (buf + 2, vma);
- }
-}
-
-/* Start a new compilation unit. */
-
-static boolean
-pr_start_compilation_unit (p, filename)
- PTR p;
- const char *filename;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->indent == 0);
-/*
- TRACE_FPRINTF( (info->f, "%s:\n", filename));
-*/
- return true;
-}
-
-/* Start a source file within a compilation unit. */
-
-static boolean
-pr_start_source (p, filename)
- PTR p;
- const char *filename;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->indent == 0);
-/*
- TRACE_FPRINTF( (info->f, " %s:\n", filename));
-*/
- return true;
-}
-
-/* Push an empty type onto the type stack. */
-
-static boolean
-pr_empty_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return push_type (info, "<undefined>");
-}
-
-/* Push a void type onto the type stack. */
-
-static boolean
-pr_void_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return push_type (info, "void");
-}
-
-/* Push an integer type onto the type stack. */
-
-static boolean
-pr_int_type (p, size, unsignedp)
- PTR p;
- unsigned int size;
- boolean unsignedp;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[10];
-
- sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
- return push_type (info, ab);
-}
-
-/* Push a floating type onto the type stack. */
-
-static boolean
-pr_float_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[10];
-
- if (size == 4)
- return push_type (info, "float");
- else if (size == 8)
- return push_type (info, "double");
-
- sprintf (ab, "float%d", size * 8);
- return push_type (info, ab);
-}
-
-/* Push a complex type onto the type stack. */
-
-static boolean
-pr_complex_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- if (! pr_float_type (p, size))
- return false;
-
- return prepend_type (info, "complex ");
-}
-
-/* Push a boolean type onto the type stack. */
-
-static boolean
-pr_bool_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[10];
-
- sprintf (ab, "bool%d", size * 8);
-
- return push_type (info, ab);
-}
-
-/* Push an enum type onto the type stack. */
-
-static boolean
-pr_enum_type (p, tag, names, values)
- PTR p;
- const char *tag;
- const char **names;
- bfd_signed_vma *values;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- unsigned int i;
- bfd_signed_vma val;
-
- if (! push_type (info, "enum "))
- return false;
- if (tag != NULL)
- {
- if (! append_type (info, tag)
- || ! append_type (info, " "))
- return false;
- }
- if (! append_type (info, "{ "))
- return false;
-
- if (names == NULL)
- {
- if (! append_type (info, "/* undefined */"))
- return false;
- }
- else
- {
- val = 0;
- for (i = 0; names[i] != NULL; i++)
- {
- if (i > 0)
- {
- if (! append_type (info, ", "))
- return false;
- }
-
- if (! append_type (info, names[i]))
- return false;
-
- if (values[i] != val)
- {
- char ab[20];
-
- print_vma (values[i], ab, false, false);
- if (! append_type (info, " = ")
- || ! append_type (info, ab))
- return false;
- val = values[i];
- }
-
- ++val;
- }
- }
-
- return append_type (info, " }");
-}
-
-/* Turn the top type on the stack into a pointer. */
-
-static boolean
-pr_pointer_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *s;
-
- assert (info->stack != NULL);
-
- s = strchr (info->stack->type, '|');
- if (s != NULL && s[1] == '[')
- return substitute_type (info, "(*|)");
- return substitute_type (info, "*|");
-}
-
-/* Turn the top type on the stack into a function returning that type. */
-
-static boolean
-pr_function_type (p, argcount, varargs)
- PTR p;
- int argcount;
- boolean varargs;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char **arg_types;
- unsigned int len;
- char *s;
-
- assert (info->stack != NULL);
-
- len = 10;
-
- if (argcount <= 0)
- {
- arg_types = NULL;
- len += 15;
- }
- else
- {
- int i;
-
- arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
- for (i = argcount - 1; i >= 0; i--)
- {
- if (! substitute_type (info, ""))
- return false;
- arg_types[i] = pop_type (info);
- if (arg_types[i] == NULL)
- return false;
- len += strlen (arg_types[i]) + 2;
- }
- if (varargs)
- len += 5;
- }
-
- /* Now the return type is on the top of the stack. */
-
- s = (char *) xmalloc (len);
- strcpy (s, "(|) (");
-
- if (argcount < 0)
- {
-#if 0
- /* Turn off unknown arguments. */
- strcat (s, "/* unknown */");
-#endif
- }
- else
- {
- int i;
-
- for (i = 0; i < argcount; i++)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, arg_types[i]);
- }
- if (varargs)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, "...");
- }
- if (argcount > 0)
- free (arg_types);
- }
-
- strcat (s, ")");
-
- if (! substitute_type (info, s))
- return false;
-
- free (s);
-
- return true;
-}
-
-/* Turn the top type on the stack into a reference to that type. */
-
-static boolean
-pr_reference_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->stack != NULL);
-
- return substitute_type (info, "&|");
-}
-
-/* Make a range type. */
-
-static boolean
-pr_range_type (p, lower, upper)
- PTR p;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char abl[20], abu[20];
-
- assert (info->stack != NULL);
-
- if (! substitute_type (info, ""))
- return false;
-
- print_vma (lower, abl, false, false);
- print_vma (upper, abu, false, false);
-
- return (prepend_type (info, "range (")
- && append_type (info, "):")
- && append_type (info, abl)
- && append_type (info, ":")
- && append_type (info, abu));
-}
-
-/* Make an array type. */
-
-/*ARGSUSED*/
-static boolean
-pr_array_type (p, lower, upper, stringp)
- PTR p;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
- boolean stringp;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *range_type;
- char abl[20], abu[20], ab[50];
-
- range_type = pop_type (info);
- if (range_type == NULL)
- return false;
-
- if (lower == 0)
- {
- if (upper == -1)
- sprintf (ab, "|[]");
- else
- {
- print_vma (upper + 1, abu, false, false);
- sprintf (ab, "|[%s]", abu);
- }
- }
- else
- {
- print_vma (lower, abl, false, false);
- print_vma (upper, abu, false, false);
- sprintf (ab, "|[%s:%s]", abl, abu);
- }
-
- if (! substitute_type (info, ab))
- return false;
-
- if (strcmp (range_type, "int") != 0)
- {
- if (! append_type (info, ":")
- || ! append_type (info, range_type))
- return false;
- }
-
- if (stringp)
- {
- if (! append_type (info, " /* string */"))
- return false;
- }
-
- return true;
-}
-
-/* Make a set type. */
-
-/*ARGSUSED*/
-static boolean
-pr_set_type (p, bitstringp)
- PTR p;
- boolean bitstringp;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- if (! substitute_type (info, ""))
- return false;
-
- if (! prepend_type (info, "set { ")
- || ! append_type (info, " }"))
- return false;
-
- if (bitstringp)
- {
- if (! append_type (info, "/* bitstring */"))
- return false;
- }
-
- return true;
-}
-
-/* Make an offset type. */
-
-static boolean
-pr_offset_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- if (! substitute_type (info, ""))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- return (substitute_type (info, "")
- && prepend_type (info, " ")
- && prepend_type (info, t)
- && append_type (info, "::|"));
-}
-
-/* Make a method type. */
-
-static boolean
-pr_method_type (p, domain, argcount, varargs)
- PTR p;
- boolean domain;
- int argcount;
- boolean varargs;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- unsigned int len;
- char *domain_type;
- char **arg_types;
- char *s;
-
- len = 10;
-
- if (! domain)
- domain_type = NULL;
- else
- {
- if (! substitute_type (info, ""))
- return false;
- domain_type = pop_type (info);
- if (domain_type == NULL)
- return false;
- if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
- && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
- domain_type += sizeof "class " - 1;
- else if (strncmp (domain_type, "union class ",
- sizeof "union class ") == 0
- && (strchr (domain_type + sizeof "union class " - 1, ' ')
- == NULL))
- domain_type += sizeof "union class " - 1;
- len += strlen (domain_type);
- }
-
- if (argcount <= 0)
- {
- arg_types = NULL;
- len += 15;
- }
- else
- {
- int i;
-
- arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
- for (i = argcount - 1; i >= 0; i--)
- {
- if (! substitute_type (info, ""))
- return false;
- arg_types[i] = pop_type (info);
- if (arg_types[i] == NULL)
- return false;
- len += strlen (arg_types[i]) + 2;
- }
- if (varargs)
- len += 5;
- }
-
- /* Now the return type is on the top of the stack. */
-
- s = (char *) xmalloc (len);
- if (! domain)
- *s = '\0';
- else
- strcpy (s, domain_type);
- strcat (s, "::| (");
-
- if (argcount < 0)
- strcat (s, "/* unknown */");
- else
- {
- int i;
-
- for (i = 0; i < argcount; i++)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, arg_types[i]);
- }
- if (varargs)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, "...");
- }
- if (argcount > 0)
- free (arg_types);
- }
-
- strcat (s, ")");
-
- if (! substitute_type (info, s))
- return false;
-
- free (s);
-
- return true;
-}
-
-/* Make a const qualified type. */
-
-static boolean
-pr_const_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return substitute_type (info, "const |");
-}
-
-/* Make a volatile qualified type. */
-
-static boolean
-pr_volatile_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return substitute_type (info, "volatile |");
-}
-
-/* Start accumulating a struct type. */
-
-static boolean
-pr_start_struct_type (p, tag, id, structp, size)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- info->indent += 2;
-
- if (! push_type (info, structp ? "struct " : "union "))
- return false;
- if (tag != NULL)
- {
- if (! append_type (info, tag))
- return false;
- }
- else
- {
- char idbuf[20];
-
- sprintf (idbuf, "%%anon%u", id);
- if (! append_type (info, idbuf))
- return false;
- }
-
- if (! append_type (info, " {"))
- return false;
- if (size != 0 || tag != NULL)
- {
- char ab[30];
-
- if (! append_type (info, " /*"))
- return false;
-
- if (size != 0)
- {
- sprintf (ab, " size %u", size);
- if (! append_type (info, ab))
- return false;
- }
- if (tag != NULL)
- {
- sprintf (ab, " id %u", id);
- if (! append_type (info, ab))
- return false;
- }
- if (! append_type (info, " */"))
- return false;
- }
- if (! append_type (info, "\n"))
- return false;
-
- info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
-
- return indent_type (info);
-}
-
-/* Output the visibility of a field in a struct. */
-
-static boolean
-pr_fix_visibility (info, visibility)
- struct pr_handle *info;
- enum debug_visibility visibility;
-{
- const char *s;
- char *t;
- unsigned int len;
-
- assert (info->stack != NULL);
-
- if (info->stack->visibility == visibility)
- return true;
-
- assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
-
- switch (visibility)
- {
- case DEBUG_VISIBILITY_PUBLIC:
- s = "public";
- break;
- case DEBUG_VISIBILITY_PRIVATE:
- s = "private";
- break;
- case DEBUG_VISIBILITY_PROTECTED:
- s = "protected";
- break;
- case DEBUG_VISIBILITY_IGNORE:
- s = "/* ignore */";
- break;
- default:
- abort ();
- return false;
- }
-
- /* Trim off a trailing space in the struct string, to make the
- output look a bit better, then stick on the visibility string. */
-
- t = info->stack->type;
- len = strlen (t);
- assert (t[len - 1] == ' ');
- t[len - 1] = '\0';
-
- if (! append_type (info, s)
- || ! append_type (info, ":\n")
- || ! indent_type (info))
- return false;
-
- info->stack->visibility = visibility;
-
- return true;
-}
-
-/* Add a field to a struct type. */
-
-static boolean
-pr_struct_field (p, name, bitpos, bitsize, visibility)
- PTR p;
- const char *name;
- bfd_vma bitpos;
- bfd_vma bitsize;
- enum debug_visibility visibility;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- char *t;
-
- if (! substitute_type (info, name))
- return false;
-
- if (! append_type (info, "; /* "))
- return false;
-
- if (bitsize != 0)
- {
- print_vma (bitsize, ab, true, false);
- if (! append_type (info, "bitsize ")
- || ! append_type (info, ab)
- || ! append_type (info, ", "))
- return false;
- }
-
- print_vma (bitpos, ab, true, false);
- if (! append_type (info, "bitpos ")
- || ! append_type (info, ab)
- || ! append_type (info, " */\n")
- || ! indent_type (info))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- return append_type (info, t);
-}
-
-/* Finish a struct type. */
-
-static boolean
-pr_end_struct_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *s;
-
- assert (info->stack != NULL);
- assert (info->indent >= 2);
-
- info->indent -= 2;
-
- /* Change the trailing indentation to have a close brace. */
- s = info->stack->type + strlen (info->stack->type) - 2;
- assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
-
- *s++ = '}';
- *s = '\0';
-
- return true;
-}
-
-/* Start a class type. */
-
-static boolean
-pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
- boolean vptr;
- boolean ownvptr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *tv = NULL;
-
- info->indent += 2;
-
- if (vptr && ! ownvptr)
- {
- tv = pop_type (info);
- if (tv == NULL)
- return false;
- }
-
- if (! push_type (info, structp ? "class " : "union class "))
- return false;
- if (tag != NULL)
- {
- if (! append_type (info, tag))
- return false;
- }
- else
- {
- char idbuf[20];
-
- sprintf (idbuf, "%%anon%u", id);
- if (! append_type (info, idbuf))
- return false;
- }
-
- if (! append_type (info, " {"))
- return false;
- if (size != 0 || vptr || ownvptr || tag != NULL)
- {
- if (! append_type (info, " /*"))
- return false;
-
- if (size != 0)
- {
- char ab[20];
-
- sprintf (ab, "%u", size);
- if (! append_type (info, " size ")
- || ! append_type (info, ab))
- return false;
- }
-
- if (vptr)
- {
- if (! append_type (info, " vtable "))
- return false;
- if (ownvptr)
- {
- if (! append_type (info, "self "))
- return false;
- }
- else
- {
- if (! append_type (info, tv)
- || ! append_type (info, " "))
- return false;
- }
- }
-
- if (tag != NULL)
- {
- char ab[30];
-
- sprintf (ab, " id %u", id);
- if (! append_type (info, ab))
- return false;
- }
-
- if (! append_type (info, " */"))
- return false;
- }
-
- info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
-
- return (append_type (info, "\n")
- && indent_type (info));
-}
-
-/* Add a static member to a class. */
-
-static boolean
-pr_class_static_member (p, name, physname, visibility)
- PTR p;
- const char *name;
- const char *physname;
- enum debug_visibility visibility;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- if (! substitute_type (info, name))
- return false;
-
- if (! prepend_type (info, "static ")
- || ! append_type (info, "; /* ")
- || ! append_type (info, physname)
- || ! append_type (info, " */\n")
- || ! indent_type (info))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- return append_type (info, t);
-}
-
-/* Add a base class to a class. */
-
-static boolean
-pr_class_baseclass (p, bitpos, virtual, visibility)
- PTR p;
- bfd_vma bitpos;
- boolean virtual;
- enum debug_visibility visibility;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
- const char *prefix;
- char ab[20];
- char *s, *l, *n;
-
- assert (info->stack != NULL && info->stack->next != NULL);
-
- if (! substitute_type (info, ""))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- if (strncmp (t, "class ", sizeof "class " - 1) == 0)
- t += sizeof "class " - 1;
-
- /* Push it back on to take advantage of the prepend_type and
- append_type routines. */
- if (! push_type (info, t))
- return false;
-
- if (virtual)
- {
- if (! prepend_type (info, "virtual "))
- return false;
- }
-
- switch (visibility)
- {
- case DEBUG_VISIBILITY_PUBLIC:
- prefix = "public ";
- break;
- case DEBUG_VISIBILITY_PROTECTED:
- prefix = "protected ";
- break;
- case DEBUG_VISIBILITY_PRIVATE:
- prefix = "private ";
- break;
- default:
- prefix = "/* unknown visibility */ ";
- break;
- }
-
- if (! prepend_type (info, prefix))
- return false;
-
- if (bitpos != 0)
- {
- print_vma (bitpos, ab, true, false);
- if (! append_type (info, " /* bitpos ")
- || ! append_type (info, ab)
- || ! append_type (info, " */"))
- return false;
- }
-
- /* Now the top of the stack is something like "public A / * bitpos
- 10 * /". The next element on the stack is something like "class
- xx { / * size 8 * /\n...". We want to substitute the top of the
- stack in before the {. */
- s = strchr (info->stack->next->type, '{');
- assert (s != NULL);
- --s;
-
- /* If there is already a ':', then we already have a baseclass, and
- we must append this one after a comma. */
- for (l = info->stack->next->type; l != s; l++)
- if (*l == ':')
- break;
- if (! prepend_type (info, l == s ? " : " : ", "))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
- memcpy (n, info->stack->type, s - info->stack->type);
- strcpy (n + (s - info->stack->type), t);
- strcat (n, s);
-
- free (info->stack->type);
- info->stack->type = n;
-
- free (t);
-
- return true;
-}
-
-/* Start adding a method to a class. */
-
-static boolean
-pr_class_start_method (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->stack != NULL);
- info->stack->method = name;
- return true;
-}
-
-/* Add a variant to a method. */
-
-static boolean
-pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
- context)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- boolean context;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *method_type;
- char *context_type;
-
- assert (info->stack != NULL);
- assert (info->stack->next != NULL);
-
- /* Put the const and volatile qualifiers on the type. */
- if (volatilep)
- {
- if (! append_type (info, " volatile"))
- return false;
- }
- if (constp)
- {
- if (! append_type (info, " const"))
- return false;
- }
-
- /* Stick the name of the method into its type. */
- if (! substitute_type (info,
- (context
- ? info->stack->next->next->method
- : info->stack->next->method)))
- return false;
-
- /* Get the type. */
- method_type = pop_type (info);
- if (method_type == NULL)
- return false;
-
- /* Pull off the context type if there is one. */
- if (! context)
- context_type = NULL;
- else
- {
- context_type = pop_type (info);
- if (context_type == NULL)
- return false;
- }
-
- /* Now the top of the stack is the class. */
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- if (! append_type (info, method_type)
- || ! append_type (info, " /* ")
- || ! append_type (info, physname)
- || ! append_type (info, " "))
- return false;
- if (context || voffset != 0)
- {
- char ab[20];
-
- if (context)
- {
- if (! append_type (info, "context ")
- || ! append_type (info, context_type)
- || ! append_type (info, " "))
- return false;
- }
- print_vma (voffset, ab, true, false);
- if (! append_type (info, "voffset ")
- || ! append_type (info, ab))
- return false;
- }
-
- return (append_type (info, " */;\n")
- && indent_type (info));
-}
-
-/* Add a static variant to a method. */
-
-static boolean
-pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *method_type;
-
- assert (info->stack != NULL);
- assert (info->stack->next != NULL);
- assert (info->stack->next->method != NULL);
-
- /* Put the const and volatile qualifiers on the type. */
- if (volatilep)
- {
- if (! append_type (info, " volatile"))
- return false;
- }
- if (constp)
- {
- if (! append_type (info, " const"))
- return false;
- }
-
- /* Mark it as static. */
- if (! prepend_type (info, "static "))
- return false;
-
- /* Stick the name of the method into its type. */
- if (! substitute_type (info, info->stack->next->method))
- return false;
-
- /* Get the type. */
- method_type = pop_type (info);
- if (method_type == NULL)
- return false;
-
- /* Now the top of the stack is the class. */
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- return (append_type (info, method_type)
- && append_type (info, " /* ")
- && append_type (info, physname)
- && append_type (info, " */;\n")
- && indent_type (info));
-}
-
-/* Finish up a method. */
-
-static boolean
-pr_class_end_method (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- info->stack->method = NULL;
- return true;
-}
-
-/* Finish up a class. */
-
-static boolean
-pr_end_class_type (p)
- PTR p;
-{
- return pr_end_struct_type (p);
-}
-
-/* Push a type on the stack using a typedef name. */
-
-static boolean
-pr_typedef_type (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return push_type (info, name);
-}
-
-/* Push a type on the stack using a tag name. */
-
-static boolean
-pr_tag_type (p, name, id, kind)
- PTR p;
- const char *name;
- unsigned int id;
- enum debug_type_kind kind;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- const char *t, *tag;
- char idbuf[30];
-
- switch (kind)
- {
- case DEBUG_KIND_STRUCT:
- t = "struct ";
- break;
- case DEBUG_KIND_UNION:
- t = "union ";
- break;
- case DEBUG_KIND_ENUM:
- t = "enum ";
- break;
- case DEBUG_KIND_CLASS:
- t = "class ";
- break;
- case DEBUG_KIND_UNION_CLASS:
- t = "union class ";
- break;
- default:
- abort ();
- return false;
- }
-
- if (! push_type (info, t))
- return false;
- if (name != NULL)
- tag = name;
- else
- {
- sprintf (idbuf, "%%anon%u", id);
- tag = idbuf;
- }
-
- if (! append_type (info, tag))
- return false;
- if (name != NULL && kind != DEBUG_KIND_ENUM)
- {
- sprintf (idbuf, " /* id %u */", id);
- if (! append_type (info, idbuf))
- return false;
- }
-
- return true;
-}
-
-/* Output a typedef. */
-
-static boolean
-pr_typdef (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *s;
-
- if (! substitute_type (info, name))
- return false;
-
- s = pop_type (info);
- if (s == NULL)
- return false;
-/*
- indent (info);
- TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
-*/
- free (s);
-
- return true;
-}
-
-/* Output a tag. The tag should already be in the string on the
- stack, so all we have to do here is print it out. */
-
-/*ARGSUSED*/
-static boolean
-pr_tag (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-/*
- indent (info);
- TRACE_FPRINTF( (info->f, "%s;\n", t));
-*/
- free (t);
-
- return true;
-}
-
-/* Output an integer constant. */
-
-static boolean
-pr_int_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
-/*
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- indent (info);
- print_vma (val, ab, false, false);
- TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
- */
- return true;
-}
-
-/* Output a floating point constant. */
-
-static boolean
-pr_float_constant (p, name, val)
- PTR p;
- const char *name;
- double val;
-{
-/*
- struct pr_handle *info = (struct pr_handle *) p;
- indent (info);
- TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
- */
- return true;
-}
-
-/* Output a typed constant. */
-
-static boolean
-pr_typed_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-/*
- char ab[20];
- indent (info);
- print_vma (val, ab, false, false);
- TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
-*/
- free (t);
-
- return true;
-}
-
-/* Output a variable. */
-
-static boolean
-pr_variable (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
- char ab[20];
- (void)ab;
-
- if (! substitute_type (info, name))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
-#if 0
- indent (info);
- switch (kind)
- {
- case DEBUG_STATIC:
- case DEBUG_LOCAL_STATIC:
- TRACE_FPRINTF( (info->f, "static "));
- break;
- case DEBUG_REGISTER:
- TRACE_FPRINTF( (info->f, "register "));
- break;
- default:
- break;
- }
- print_vma (val, ab, true, true);
- TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
-#else /* 0 */
-#if 0
- if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
- print_vma (val, ab, true, true);
- TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
- }
-#endif /* 0 */
-#endif /* !0 */
-
- free (t);
-
- return true;
-}
-
-/* Start outputting a function. */
-
-static boolean
-pr_start_function (p, name, global)
- PTR p;
- const char *name;
- boolean global;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- if (! substitute_type (info, name))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
-#if 0
- indent (info);
- if (! global)
- TRACE_FPRINTF( (info->f, "static "));
- TRACE_FPRINTF( (info->f, "%s (", t));
- info->parameter = 1;
-#else /* 0 */
- if (info->functions_size==info->functions_maxsize) {
- info->functions_maxsize *= 2;
- info->functions = xrealloc(info->functions,
- info->functions_maxsize*sizeof(debug_function_t));
- assert(info->functions!=0);
- }
- /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
- info->function = &info->functions[info->functions_size];
- ++info->functions_size;
- info->function->symbol = NULL;
- info->function->lines = NULL;
- info->function->lines_count = 0;
- info->function->max_lines_count = 0;
- info->function->name = t;
- info->function->filename = NULL;
- info->function->block = NULL;
- info->function->argv = NULL;
- info->function->argc = 0;
- info->function->max_argc = 0;
-#endif /* !0 */
- return true;
-}
-
-/* Output a function parameter. */
-
-static boolean
-pr_function_parameter (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_parm_kind kind;
- bfd_vma val;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- debug_function_t* f = info->function;
- char *t;
- char ab[20];
- (void)ab;
-
- if (kind == DEBUG_PARM_REFERENCE
- || kind == DEBUG_PARM_REF_REG)
- {
- if (! pr_reference_type (p))
- return false;
- }
-
- if (! substitute_type (info, name))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
-#if 0
- if (info->parameter != 1)
- TRACE_FPRINTF( (info->f, ", "));
-
- if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
- TRACE_FPRINTF( (info->f, "register "));
-
- print_vma (val, ab, true, true);
- TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
- free (t);
- ++info->parameter;
-#else /* 0 */
- assert(f!=NULL);
- if (f->argv==NULL) {
- f->max_argc = 7; /* rarely anyone has more than that many args... */
- f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
- } else if (f->argc==f->max_argc) {
- f->max_argc *= 2;
- f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
- }
- f->argv[f->argc].offset = val;
- f->argv[f->argc].name = t;
- ++f->argc;
-#endif /* !0 */
- return true;
-}
-
-/* Start writing out a block. */
-
-static boolean
-pr_start_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- debug_block_t* block = 0;
- (void)ab;
-#if 0
- if (info->parameter > 0)
- {
- TRACE_FPRINTF( (info->f, ")\n"));
- info->parameter = 0;
- }
- indent (info);
- print_vma (addr, ab, true, true);
- TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
- info->indent += 2;
-#else
- if (info->block) {
- if (info->block->childs_count==0)
- info->block->childs = xmalloc(sizeof(debug_block_t));
- else
- info->block->childs = xrealloc(info->block->childs,
- info->block->childs_count*sizeof(debug_block_t));
- block = &info->block->childs[info->block->childs_count];
- } else {
- block = xmalloc(sizeof(debug_block_t));
- info->function->block = block;
- }
- block->begin_addr = addr;
- block->end_addr = 0;
- block->parent = info->block;
- block->childs = NULL;
- block->childs_count = 0;
- info->block = block;
-#endif
- return true;
-}
-
-/* Write out line number information. */
-
-static boolean
-pr_lineno (p, filename, lineno, addr)
- PTR p;
- const char *filename;
- unsigned long lineno;
- bfd_vma addr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- debug_function_t* f = info->function;
- (void)ab;
-
-#if 0
- indent (info);
- print_vma (addr, ab, true, true);
- TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
-#else /* 0 */
- if (f==NULL) /* FIXME: skips junk silently. */
- return true;
- /* assert(f!=NULL); */
- if (f->filename==NULL) {
- f->filename = filename;
- assert(f->lines==0);
- f->max_lines_count = 4;
- f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
- }
- if (f->lines_count==f->max_lines_count) {
- f->max_lines_count *= 2;
- f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
- }
- f->lines[f->lines_count].lineno = lineno;
- f->lines[f->lines_count].addr = addr;
- ++f->lines_count;
-#endif /* !0 */
-
- return true;
-}
-
-/* Finish writing out a block. */
-
-static boolean
-pr_end_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
-#if 0
- char ab[20];
-
- info->indent -= 2;
- indent (info);
- print_vma (addr, ab, true, true);
- TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
-#else /* 0 */
- assert(info->block!=0);
- info->block->end_addr = addr;
- info->block = info->block->parent;
-#endif /* !0 */
-
- return true;
-}
-
-/* Finish writing out a function. */
-
-/*ARGSUSED*/
-static boolean
-pr_end_function (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- assert(info->block==0);
- info->function = NULL;
- return true;
-}
-
-/* third parameter to segv_action. */
-/* Got it after a bit of head scratching and stack dumping. */
-typedef struct {
- u_int32_t foo1; /* +0x00 */
- u_int32_t foo2;
- u_int32_t foo3;
- u_int32_t foo4; /* usually 2 */
- u_int32_t foo5; /* +0x10 */
- u_int32_t xgs; /* always zero */
- u_int32_t xfs; /* always zero */
- u_int32_t xes; /* always es=ds=ss */
- u_int32_t xds; /* +0x20 */
- u_int32_t edi;
- u_int32_t esi;
- u_int32_t ebp;
- u_int32_t esp; /* +0x30 */
- u_int32_t ebx;
- u_int32_t edx;
- u_int32_t ecx;
- u_int32_t eax; /* +0x40 */
- u_int32_t foo11; /* usually 0xe */
- u_int32_t foo12; /* usually 0x6 */
- u_int32_t eip; /* instruction pointer */
- u_int32_t xcs; /* +0x50 */
- u_int32_t foo21; /* usually 0x2 */
- u_int32_t foo22; /* second stack pointer?! Probably. */
- u_int32_t xss;
- u_int32_t foo31; /* +0x60 */ /* usually 0x0 */
- u_int32_t foo32; /* usually 0x2 */
- u_int32_t fault_addr; /* Address which caused a fault */
- u_int32_t foo41; /* usually 0x2 */
-} signal_regs_t;
-
-signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */
-/*
- * my_ptrace: small wrapper around ptrace.
- * Act as normal ptrace if ptrace_regs==0.
- * Read data from current process if ptrace_regs!=0.
- */
-static int
-my_ptrace( int request,
- int pid,
- int addr,
- int data)
-{
- if (ptrace_regs==0)
- return ptrace(request, pid, addr, data);
- /* we are tracing ourselves! */
- switch (request) {
- case PTRACE_ATTACH: return 0;
- case PTRACE_CONT: return 0;
- case PTRACE_DETACH: return 0;
- case PTRACE_PEEKUSER:
- switch (addr / 4) {
- case EIP: return ptrace_regs->eip;
- case EBP: return ptrace_regs->ebp;
- default: assert(0);
- }
- case PTRACE_PEEKTEXT: /* FALLTHROUGH */
- case PTRACE_PEEKDATA: return *(int*)(addr);
- default: assert(0);
- }
- errno = 1; /* what to do here? */
- return 1; /* failed?! */
-}
-
-#define MAXARGS 6
-
-/*
- * To minimize the number of parameters.
- */
-typedef struct {
- asymbol** syms; /* Sorted! */
- int symcount;
- debug_function_t** functions;
- int functions_size;
-} symbol_data_t;
-
-/*
- * Perform a search. A binary search for a symbol.
- */
-static void
-decode_symbol( symbol_data_t* symbol_data,
- const unsigned long addr,
- char* buf,
- const int bufsize)
-{
- asymbol** syms = symbol_data->syms;
- const int symcount = symbol_data->symcount;
- int bottom = 0;
- int top = symcount - 1;
- int i;
- if (symcount==0) {
- sprintf(buf, "????");
- return;
- }
- while (top>bottom+1) {
- i = (top+bottom) / 2;
- if (bfd_asymbol_value(syms[i])==addr) {
- sprintf(buf, "%s", syms[i]->name);
- return;
- } else if (bfd_asymbol_value(syms[i]) > addr)
- top = i;
- else
- bottom = i;
- }
- i = bottom;
- if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
- sprintf(buf, "????");
- else
- sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
-}
-
-/*
- * 1. Perform a binary search for an debug_function_t.
- * 2. Fill buf/bufsize with name, parameters and lineno, if found
- * Or with '????' otherwise.
- */
-static debug_function_t*
-find_debug_function_t( symbol_data_t* symbol_data,
- const pid_t pid,
- const unsigned long fp, /* frame pointer */
- const unsigned long addr,
- char* buf, /* string buffer */
- const int bufsize)/* FIXME: not used! */
-{
- debug_function_t** syms = symbol_data->functions;
- debug_function_t* f = NULL;
- debug_block_t* block = NULL;
- debug_lineno_t* lineno = NULL;
- const int symcount = symbol_data->functions_size;
- int bottom = 0;
- int top = symcount - 1;
- int i;
- char* bufptr = buf;
-
- if (symcount==0) {
- sprintf(buf, "????");
- return NULL;
- }
- while (top>bottom+1) {
- i = (top+bottom) / 2;
- if (syms[i]->block->begin_addr==addr) {
- f = syms[i];
- break;
- } else if (syms[i]->block->begin_addr > addr)
- top = i;
- else
- if (syms[i]->block->end_addr >= addr) {
- f = syms[i];
- break;
- } else
- bottom = i;
- }
- i = bottom;
- if (f!=0)
- block = f->block;
- else {
- block = syms[i]->block;
- if (block->begin_addr>=addr && block->end_addr<=addr)
- f = syms[i];
- }
- if (f==0)
- sprintf(buf, "????");
- else {
- /*
- * Do the backtrace the GDB way...
- */
- unsigned long arg;
- /* assert(f->lines_count>0); */
- if (f->lines_count>0) {
- lineno = &f->lines[f->lines_count-1];
- for (i=1; i<f->lines_count; ++i)
- if (f->lines[i].addr>addr) {
- lineno = &f->lines[i-1];
- break;
- }
- }
- bufptr[0] = 0;
- bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
- for (i=0; i<f->argc; ++i) {
- bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
- /* FIXME: better parameter printing */
- errno = 0;
- arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
- assert(errno==0);
- bufptr += sprintf(bufptr, "0x%x", arg);
- if (i!=f->argc-1)
- bufptr += sprintf(bufptr, ", ");
- }
- if (lineno!=0)
- bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
- }
- return f;
-}
-
-/*
- * Advance through the stacks and display frames as needed.
- */
-static int
-my_crawl( int pid,
- symbol_data_t* symbol_data,
- int fout)
-{
- unsigned long pc = 0;
- unsigned long fp = 0;
- unsigned long nextfp;
- unsigned long nargs;
- unsigned long i;
- unsigned long arg;
- char buf[8096]; // FIXME: enough?
- debug_function_t* f = 0;
-
- errno = 0;
-
- pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
- if (!errno)
- fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
-
- if (!errno) {
-#if 1
- f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- for ( ; !errno && fp; ) {
- nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
- if (errno)
- break;
-
- if (f==0) {
- nargs = (nextfp - fp - 8) / 4;
- if (nargs > MAXARGS)
- nargs = MAXARGS;
- if (nargs > 0) {
- fdputs(" (", fout);
- for (i = 1; i <= nargs; i++) {
- arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
- if (errno)
- break;
- fdprintf(fout,"%lx", arg);
- if (i < nargs)
- fdputs(", ", fout);
- }
- fdputc(')', fout);
- nargs = nextfp - fp - 8 - (4 * nargs);
- if (!errno && nargs > 0)
- fdprintf(fout," + %lx\n", nargs);
- else
- fdputc('\n', fout);
- } else
- fdputc('\n', fout);
- } else
- fdputc('\n', fout);
-
- if (errno || !nextfp)
- break;
- pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
- fp = nextfp;
- if (errno)
- break;
- f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- }
-#else /* 1 */
- decode_symbol(symbol_data, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- for ( ; !errno && fp; ) {
- nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
- if (errno)
- break;
-
- nargs = (nextfp - fp - 8) / 4;
- if (nargs > MAXARGS)
- nargs = MAXARGS;
- if (nargs > 0) {
- fputs(" (", fout);
- for (i = 1; i <= nargs; i++) {
- arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
- if (errno)
- break;
- fdprintf(fout,"%lx", arg);
- if (i < nargs)
- fputs(", ", fout);
- }
- fdputc(')', fout);
- nargs = nextfp - fp - 8 - (4 * nargs);
- if (!errno && nargs > 0)
- fdprintf(fout," + %lx\n", nargs);
- else
- fdputc('\n', fout);
- } else
- fdputc('\n', fout);
-
- if (errno || !nextfp)
- break;
- pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
- fp = nextfp;
- if (errno)
- break;
- decode_symbol(symbol_data, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- }
-#endif /* !1 */
- }
- if (errno)
- perror("my_crawl");
- return errno;
-}
-
-/* layout from /usr/src/linux/arch/i386/kernel/process.c */
-static void
-show_regs( signal_regs_t* regs,
- int fd)
-{
- /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
-
- fdprintf(fd,"\n");
- fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
- fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
- if (regs->xcs & 3)
- fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
- /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
- fdprintf(fd, "\n");
- fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
- regs->eax,regs->ebx,regs->ecx,regs->edx);
- fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
- regs->esi, regs->edi, regs->ebp);
- fdprintf(fd," DS: %04x ES: %04x\n",
- 0xffff & regs->xds,0xffff & regs->xes);
- /*
- __asm__("movl %%cr0, %0": "=r" (cr0));
- __asm__("movl %%cr2, %0": "=r" (cr2));
- __asm__("movl %%cr3, %0": "=r" (cr3));
- fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
-}
-
-/*
- * Load a BFD for an executable based on PID. Return 0 on failure.
- */
-static bfd*
-load_bfd( const int pid)
-{
- char filename[512];
- bfd* abfd = 0;
-
- /* Get the contents from procfs. */
-#if 1
- sprintf(filename, "/proc/%d/exe", pid);
-#else
- sprintf(filename, "crashing");
-#endif
-
- if ((abfd = bfd_openr (filename, 0))== NULL)
- bfd_nonfatal (filename);
- else {
- char** matching;
- assert(bfd_check_format(abfd, bfd_archive)!=true);
-
- /*
- * There is no indication in BFD documentation that it should be done.
- * God knows why...
- */
- if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
- bfd_nonfatal (bfd_get_filename (abfd));
- if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
- list_matching_formats (matching);
- free (matching);
- }
- }
- }
- return abfd;
-}
-
-/*
- * Those are for qsort. We need only function addresses, so all the others don't count.
- */
-/*
- * Compare two BFD::asymbol-s.
- */
-static int
-compare_symbols(const void* ap,
- const void* bp)
-{
- const asymbol *a = *(const asymbol **)ap;
- const asymbol *b = *(const asymbol **)bp;
- if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
- return 1;
- else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
- return -1;
- return 0;
-}
-
-/*
- * Compare two debug_asymbol_t-s.
- */
-static int
-compare_debug_function_t(const void* ap,
- const void* bp)
-{
- const debug_function_t *a = *(const debug_function_t **)ap;
- const debug_function_t *b = *(const debug_function_t **)bp;
- assert(a->block!=0);
- assert(b->block!=0);
- {
- const bfd_vma addr1 = a->block->begin_addr;
- const bfd_vma addr2 = b->block->begin_addr;
- if (addr1 > addr2)
- return 1;
- else if (addr2 > addr1)
- return -1;
- }
- return 0;
-}
-
-/*
- * Filter out (in place) symbols that are useless for stack tracing.
- * COUNT is the number of elements in SYMBOLS.
- * Return the number of useful symbols.
- */
-
-static long
-remove_useless_symbols( asymbol** symbols,
- long count)
-{
- asymbol** in_ptr = symbols;
- asymbol** out_ptr = symbols;
-
- while (--count >= 0) {
- asymbol *sym = *in_ptr++;
-
- if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
- continue;
- if (sym->flags & (BSF_DEBUGGING))
- continue;
- if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
- continue;
- *out_ptr++ = sym;
- }
- return out_ptr - symbols;
-}
-
-/*
- * Debugging information.
- */
-static bfd* abfd = 0;
-static PTR dhandle = 0;
-static asymbol** syms = 0;
-static long symcount = 0;
-static asymbol** sorted_syms = 0;
-static long sorted_symcount = 0;
-static debug_function_t** functions = 0;
-static int functions_size = 0;
-static int sigreport = SIGUSR1;
-static pthread_t segv_tid; /* What thread did SEGV? */
-static pid_t segv_pid;
-
-/*
- * We'll get here after a SIGSEGV. But you can install it on other signals, too :)
- * Because we are in the middle of the SIGSEGV, we are on our own. We can't do
- * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't
- * fprintf(stderr,...)!!!
- */
-static void
-segv_action(int signo, siginfo_t* siginfo, void* ptr)
-{
- symbol_data_t symbol_data;
- int fd = -1;
-
- segv_pid = getpid();
- segv_tid = pthread_self();
- fd = open_log_file(segv_tid, segv_pid);
- /* signal(SIGSEGV, SIG_DFL); */
- ptrace_regs = (signal_regs_t*)ptr;
- assert(ptrace_regs!=0);
-
- /* Show user how guilty we are. */
- fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
- show_regs(ptrace_regs, fd);
-
- /* Some form of stack trace, too. */
- fdprintf(fd, "STACK TRACE:\n");
-
- symbol_data.syms = sorted_syms;
- symbol_data.symcount = sorted_symcount;
- symbol_data.functions = functions;
- symbol_data.functions_size = functions_size;
- my_crawl(segv_pid, &symbol_data, fd);
- //fflush(stdout);
- close(fd);
- linuxthreads_notify_others(sigreport);
-}
-
-
-static void
-report_action(int signo, siginfo_t* siginfo, void* ptr)
-{
- const int pid = getpid();
- pthread_t tid = pthread_self();
- symbol_data_t symbol_data;
- int fd;
- if (pthread_equal(tid, segv_tid)) {
- /* We have already printed our stack trace... */
- return;
- }
-
- fd = open_log_file(tid, pid);
- fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
- /* signal(SIGSEGV, SIG_DFL); */
- ptrace_regs = (signal_regs_t*)ptr;
- assert(ptrace_regs!=0);
-
- /* Show user how guilty we are. */
- fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
- show_regs(ptrace_regs, fd);
-
- /* Some form of stack trace, too. */
- fdprintf(fd, "STACK TRACE:\n");
-
- symbol_data.syms = sorted_syms;
- symbol_data.symcount = sorted_symcount;
- symbol_data.functions = functions;
- symbol_data.functions_size = functions_size;
- my_crawl(pid, &symbol_data, fd);
- //fflush(stdout);
- close(fd);
- /* Tell segv_thread to proceed after pause(). */
- /*pthread_kill(segv_tid, sigreport);
- kill(segv_pid, sigreport);
- pthread_cancel(tid); */
-}
-
-/*
- * Main library routine. Just call it on your program.
- */
-int
-pstack_install_segv_action( const char* path_format_)
-{
- const int pid = getpid();
- struct sigaction act;
-
- /* Store what we have to for later usage. */
- path_format = path_format_;
-
- /* We need a signal action for SIGSEGV and sigreport ! */
- sigreport = SIGUSR1;
- act.sa_handler = 0;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */
- act.sa_sigaction = segv_action;
- act.sa_restorer = NULL;
- if (sigaction(SIGSEGV, &act, NULL)!=0) {
- perror("sigaction");
- return 1;
- }
- act.sa_sigaction = report_action;
- act.sa_flags = SA_SIGINFO; /* But many sigreports. */
- if (sigaction(sigreport, &act, NULL)!=0) {
- perror("sigaction");
- return 1;
- }
-
- /* And a little setup for libiberty. */
- program_name = "crashing";
- xmalloc_set_program_name (program_name);
-
- /* Umm, and initialize BFD, too */
- bfd_init();
-#if 0
- list_supported_targets(0, stdout);
- set_default_bfd_target();
-#endif /* 0 */
-
- if ((abfd = load_bfd(pid))==0)
- fprintf(stderr, "BFD load failed..\n");
- else {
- long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ?
- bfd_get_symtab_upper_bound (abfd) : 0;
- long i;
- (void)i;
-
- if (storage_needed < 0)
- fprintf(stderr, "Symbol table size estimation failure.\n");
- else if (storage_needed > 0) {
- syms = (asymbol **) xmalloc (storage_needed);
- symcount = bfd_canonicalize_symtab (abfd, syms);
-
- TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
- /* We need debugging info, too! */
- if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
- fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
-
- /* We make a copy of syms to sort. We don't want to sort syms
- because that will screw up the relocs. */
- sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
- memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
-
-#if 0
- for (i=0; i<symcount; ++i)
- if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
- printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
-#endif
- sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
- TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
-
- /* Sort the symbols into section and symbol order */
- qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
-#if 0
- for (i=0; i<sorted_symcount; ++i)
- if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
- printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
-#endif
- /* We have symbols, we need debugging info somehow sorted out. */
- if (dhandle==0) {
- fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
- } else {
- /* Start collecting the debugging information.... */
- struct pr_handle info;
-
- info.f = stdout;
- info.indent = 0;
- info.stack = NULL;
- info.parameter = 0;
- info.block = NULL;
- info.function = NULL;
- info.functions_size = 0;
- info.functions_maxsize = 1000;
- info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
- debug_write (dhandle, &pr_fns, (PTR) &info);
- TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
- assert(info.functions_size!=0);
- functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
- functions_size = info.functions_size;
- for (i=0; i<functions_size; ++i)
- functions[i] = &info.functions[i];
- /* Sort the symbols into section and symbol order */
- qsort (functions, functions_size, sizeof(debug_function_t*),
- compare_debug_function_t);
-#if 0
- for (i=0; i<info.functions_size; ++i)
- fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
-#endif
- fflush(stdout);
- }
- } else /* storage_needed == 0 */
- fprintf(stderr, "NO SYMBOLS FOUND.\n");
- }
- return 0;
-}
-
-/*********************************************************************/
-/*********************************************************************/
-/*********************************************************************/
diff --git a/pstack/pstack.h b/pstack/pstack.h
deleted file mode 100644
index 4c4fad7e754..00000000000
--- a/pstack/pstack.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* $Header$ */
-
-#ifndef pstack_pstack_h_
-#define pstack_pstack_h_
-
-#include "pstacktrace.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Install the stack-trace-on-SEGV handler....
- */
-extern int
-pstack_install_segv_action( const char* path_format);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* pstack_pstack_h_ */
-
diff --git a/pstack/pstacktrace.h b/pstack/pstacktrace.h
deleted file mode 100644
index c884bcb9f87..00000000000
--- a/pstack/pstacktrace.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Header$ */
-
-/*
- * Debugging macros.
- */
-
-#ifndef pstacktrace_h_
-#define pstacktrace_h_
-
-#define PSTACK_DEBUG 1
-#undef PSTACK_DEBUG
-
-#ifdef PSTACK_DEBUG
-# define TRACE_PUTC(a) putc a
-# define TRACE_FPUTS(a) fputs a
-# define TRACE_FPRINTF(a) fprintf a
-#else /* PSTACK_DEBUG */
-# define TRACE_PUTC(a) (void)0
-# define TRACE_FPUTS(a) (void)0
-# define TRACE_FPRINTF(a) (void)0
-#endif /* !PSTACK_DEBUG */
-
-#endif /* pstacktrace_h_ */
-
diff --git a/pstack/rddbg.c b/pstack/rddbg.c
deleted file mode 100644
index be3dfc21c57..00000000000
--- a/pstack/rddbg.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/* rddbg.c -- Read debugging information into a generic form.
- Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file reads debugging information into a generic form. This
- file knows how to dig the debugging information out of an object
- file. */
-
-#include <bfd.h>
-#include "bucomm.h"
-#include <libiberty.h>
-#include "debug.h"
-#include "budbg.h"
-
-static boolean read_section_stabs_debugging_info
- PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
-static boolean read_symbol_stabs_debugging_info
- PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
-static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
-static void save_stab PARAMS ((int, int, bfd_vma, const char *));
-static void stab_context PARAMS ((void));
-static void free_saved_stabs PARAMS ((void));
-
-/* Read debugging information from a BFD. Returns a generic debugging
- pointer. */
-
-PTR
-read_debugging_info (abfd, syms, symcount)
- bfd *abfd;
- asymbol **syms;
- long symcount;
-{
- PTR dhandle;
- boolean found;
-
- dhandle = debug_init ();
- if (dhandle == NULL)
- return NULL;
-
- if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
- &found))
- return NULL;
-
- if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
- {
- if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
- &found))
- return NULL;
- }
-
- if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
- {
- if (! read_ieee_debugging_info (abfd, dhandle, &found))
- return NULL;
- }
-
- /* Try reading the COFF symbols if we didn't find any stabs in COFF
- sections. */
- if (! found
- && bfd_get_flavour (abfd) == bfd_target_coff_flavour
- && symcount > 0)
- {
-#if 0
-/*
- * JZ: Do we need coff?
- */
- if (! parse_coff (abfd, syms, symcount, dhandle))
-#else
- fprintf (stderr, "%s: COFF support temporarily disabled\n",
- bfd_get_filename (abfd));
- return NULL;
-#endif
- return NULL;
- found = true;
- }
-
- if (! found)
- {
- fprintf (stderr, "%s: no recognized debugging information\n",
- bfd_get_filename (abfd));
- return NULL;
- }
-
- return dhandle;
-}
-
-/* Read stabs in sections debugging information from a BFD. */
-
-static boolean
-read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
- bfd *abfd;
- asymbol **syms;
- long symcount;
- PTR dhandle;
- boolean *pfound;
-{
- static struct
- {
- const char *secname;
- const char *strsecname;
- } names[] = { { ".stab", ".stabstr" } };
- unsigned int i;
- PTR shandle;
-
- *pfound = false;
- shandle = NULL;
-
- for (i = 0; i < sizeof names / sizeof names[0]; i++)
- {
- asection *sec, *strsec;
-
- sec = bfd_get_section_by_name (abfd, names[i].secname);
- strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
- if (sec != NULL && strsec != NULL)
- {
- bfd_size_type stabsize, strsize;
- bfd_byte *stabs, *strings;
- bfd_byte *stab;
- bfd_size_type stroff, next_stroff;
-
- stabsize = bfd_section_size (abfd, sec);
- stabs = (bfd_byte *) xmalloc (stabsize);
- if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
- {
- fprintf (stderr, "%s: %s: %s\n",
- bfd_get_filename (abfd), names[i].secname,
- bfd_errmsg (bfd_get_error ()));
- return false;
- }
-
- strsize = bfd_section_size (abfd, strsec);
- strings = (bfd_byte *) xmalloc (strsize);
- if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
- {
- fprintf (stderr, "%s: %s: %s\n",
- bfd_get_filename (abfd), names[i].strsecname,
- bfd_errmsg (bfd_get_error ()));
- return false;
- }
-
- if (shandle == NULL)
- {
- shandle = start_stab (dhandle, abfd, true, syms, symcount);
- if (shandle == NULL)
- return false;
- }
-
- *pfound = true;
-
- stroff = 0;
- next_stroff = 0;
- for (stab = stabs; stab < stabs + stabsize; stab += 12)
- {
- bfd_size_type strx;
- int type;
- int other;
- int desc;
- bfd_vma value;
-
- /* This code presumes 32 bit values. */
-
- strx = bfd_get_32 (abfd, stab);
- type = bfd_get_8 (abfd, stab + 4);
- other = bfd_get_8 (abfd, stab + 5);
- desc = bfd_get_16 (abfd, stab + 6);
- value = bfd_get_32 (abfd, stab + 8);
-
- if (type == 0)
- {
- /* Special type 0 stabs indicate the offset to the
- next string table. */
- stroff = next_stroff;
- next_stroff += value;
- }
- else
- {
- char *f, *s;
-
- f = NULL;
- s = (char *) strings + stroff + strx;
- while (s[strlen (s) - 1] == '\\'
- && stab + 12 < stabs + stabsize)
- {
- char *p;
-
- stab += 12;
- p = s + strlen (s) - 1;
- *p = '\0';
- s = concat (s,
- ((char *) strings
- + stroff
- + bfd_get_32 (abfd, stab)),
- (const char *) NULL);
-
- /* We have to restore the backslash, because, if
- the linker is hashing stabs strings, we may
- see the same string more than once. */
- *p = '\\';
-
- if (f != NULL)
- free (f);
- f = s;
- }
-
- save_stab (type, desc, value, s);
-
- if (! parse_stab (dhandle, shandle, type, desc, value, s))
- {
-#if 0
-/*
- * JZ: skip the junk.
- */
- stab_context ();
- free_saved_stabs ();
- return false;
-#endif
- }
-
- /* Don't free f, since I think the stabs code
- expects strings to hang around. This should be
- straightened out. FIXME. */
- }
- }
-
- free_saved_stabs ();
- free (stabs);
-
- /* Don't free strings, since I think the stabs code expects
- the strings to hang around. This should be straightened
- out. FIXME. */
- }
- }
-
- if (shandle != NULL)
- {
- if (! finish_stab (dhandle, shandle))
- return false;
- }
-
- return true;
-}
-
-/* Read stabs in the symbol table. */
-
-static boolean
-read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
- bfd *abfd;
- asymbol **syms;
- long symcount;
- PTR dhandle;
- boolean *pfound;
-{
- PTR shandle;
- asymbol **ps, **symend;
-
- shandle = NULL;
- symend = syms + symcount;
- for (ps = syms; ps < symend; ps++)
- {
- symbol_info i;
-
- bfd_get_symbol_info (abfd, *ps, &i);
-
- if (i.type == '-')
- {
- const char *s;
- char *f;
-
- if (shandle == NULL)
- {
- shandle = start_stab (dhandle, abfd, false, syms, symcount);
- if (shandle == NULL)
- return false;
- }
-
- *pfound = true;
-
- s = i.name;
- f = NULL;
- while (s[strlen (s) - 1] == '\\'
- && ps + 1 < symend)
- {
- char *sc, *n;
-
- ++ps;
- sc = xstrdup (s);
- sc[strlen (sc) - 1] = '\0';
- n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
- free (sc);
- if (f != NULL)
- free (f);
- f = n;
- s = n;
- }
-
- save_stab (i.stab_type, i.stab_desc, i.value, s);
-
- if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
- i.value, s))
- {
- stab_context ();
- free_saved_stabs ();
- return false;
- }
-
- /* Don't free f, since I think the stabs code expects
- strings to hang around. This should be straightened out.
- FIXME. */
- }
- }
-
- free_saved_stabs ();
-
- if (shandle != NULL)
- {
- if (! finish_stab (dhandle, shandle))
- return false;
- }
-
- return true;
-}
-
-/* Read IEEE debugging information. */
-
-static boolean
-read_ieee_debugging_info (abfd, dhandle, pfound)
- bfd *abfd;
- PTR dhandle;
- boolean *pfound;
-{
- asection *dsec;
- bfd_size_type size;
- bfd_byte *contents;
-
- /* The BFD backend puts the debugging information into a section
- named .debug. */
-
- dsec = bfd_get_section_by_name (abfd, ".debug");
- if (dsec == NULL)
- return true;
-
- size = bfd_section_size (abfd, dsec);
- contents = (bfd_byte *) xmalloc (size);
- if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
- return false;
-
- if (! parse_ieee (dhandle, abfd, contents, size))
- return false;
-
- free (contents);
-
- *pfound = true;
-
- return true;
-}
-
-/* Record stabs strings, so that we can give some context for errors. */
-
-#define SAVE_STABS_COUNT (16)
-
-struct saved_stab
-{
- int type;
- int desc;
- bfd_vma value;
- char *string;
-};
-
-static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
-static int saved_stabs_index;
-
-/* Save a stabs string. */
-
-static void
-save_stab (type, desc, value, string)
- int type;
- int desc;
- bfd_vma value;
- const char *string;
-{
- if (saved_stabs[saved_stabs_index].string != NULL)
- free (saved_stabs[saved_stabs_index].string);
- saved_stabs[saved_stabs_index].type = type;
- saved_stabs[saved_stabs_index].desc = desc;
- saved_stabs[saved_stabs_index].value = value;
- saved_stabs[saved_stabs_index].string = xstrdup (string);
- saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
-}
-
-/* Provide context for an error. */
-
-static void
-stab_context ()
-{
- int i;
-
- fprintf (stderr, "Last stabs entries before error:\n");
- fprintf (stderr, "n_type n_desc n_value string\n");
-
- i = saved_stabs_index;
- do
- {
- struct saved_stab *stabp;
-
- stabp = saved_stabs + i;
- if (stabp->string != NULL)
- {
- const char *s;
-
- s = bfd_get_stab_name (stabp->type);
- if (s != NULL)
- fprintf (stderr, "%-6s", s);
- else if (stabp->type == 0)
- fprintf (stderr, "HdrSym");
- else
- fprintf (stderr, "%-6d", stabp->type);
- fprintf (stderr, " %-6d ", stabp->desc);
- fprintf_vma (stderr, stabp->value);
- if (stabp->type != 0)
- fprintf (stderr, " %s", stabp->string);
- fprintf (stderr, "\n");
- }
- i = (i + 1) % SAVE_STABS_COUNT;
- }
- while (i != saved_stabs_index);
-}
-
-/* Free the saved stab strings. */
-
-static void
-free_saved_stabs ()
-{
- int i;
-
- for (i = 0; i < SAVE_STABS_COUNT; i++)
- {
- if (saved_stabs[i].string != NULL)
- {
- free (saved_stabs[i].string);
- saved_stabs[i].string = NULL;
- }
- }
-
- saved_stabs_index = 0;
-}
diff --git a/pstack/stabs.c b/pstack/stabs.c
deleted file mode 100644
index 076231d19cb..00000000000
--- a/pstack/stabs.c
+++ /dev/null
@@ -1,5082 +0,0 @@
-/* stabs.c -- Parse stabs debugging information
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file contains code which parses stabs debugging information.
- The organization of this code is based on the gdb stabs reading
- code. The job it does is somewhat different, because it is not
- trying to identify the correct address for anything. */
-
-#include <stdio.h>
-#include <ctype.h>
-
-#include <bfd.h>
-#include "bucomm.h"
-#include <libiberty.h>
-#include "demangle.h"
-#include "debug.h"
-#include "budbg.h"
-
-/* Meaningless definition needs by aout64.h. FIXME. */
-#define BYTES_IN_WORD 4
-
-#include "aout/aout64.h"
-#include "aout/stab_gnu.h"
-
-/* The number of predefined XCOFF types. */
-
-#define XCOFF_TYPE_COUNT 34
-
-/* This structure is used as a handle so that the stab parsing doesn't
- need to use any static variables. */
-
-struct stab_handle
-{
- /* The BFD. */
- bfd *abfd;
- /* True if this is stabs in sections. */
- boolean sections;
- /* The symbol table. */
- asymbol **syms;
- /* The number of symbols. */
- long symcount;
- /* The accumulated file name string. */
- char *so_string;
- /* The value of the last N_SO symbol. */
- bfd_vma so_value;
- /* The value of the start of the file, so that we can handle file
- relative N_LBRAC and N_RBRAC symbols. */
- bfd_vma file_start_offset;
- /* The offset of the start of the function, so that we can handle
- function relative N_LBRAC and N_RBRAC symbols. */
- bfd_vma function_start_offset;
- /* The version number of gcc which compiled the current compilation
- unit, 0 if not compiled by gcc. */
- int gcc_compiled;
- /* Whether an N_OPT symbol was seen that was not generated by gcc,
- so that we can detect the SunPRO compiler. */
- boolean n_opt_found;
- /* The main file name. */
- char *main_filename;
- /* A stack of unfinished N_BINCL files. */
- struct bincl_file *bincl_stack;
- /* A list of finished N_BINCL files. */
- struct bincl_file *bincl_list;
- /* Whether we are inside a function or not. */
- boolean within_function;
- /* The address of the end of the function, used if we have seen an
- N_FUN symbol while in a function. This is -1 if we have not seen
- an N_FUN (the normal case). */
- bfd_vma function_end;
- /* The depth of block nesting. */
- int block_depth;
- /* List of pending variable definitions. */
- struct stab_pending_var *pending;
- /* Number of files for which we have types. */
- unsigned int files;
- /* Lists of types per file. */
- struct stab_types **file_types;
- /* Predefined XCOFF types. */
- debug_type xcoff_types[XCOFF_TYPE_COUNT];
- /* Undefined tags. */
- struct stab_tag *tags;
-};
-
-/* A list of these structures is used to hold pending variable
- definitions seen before the N_LBRAC of a block. */
-
-struct stab_pending_var
-{
- /* Next pending variable definition. */
- struct stab_pending_var *next;
- /* Name. */
- const char *name;
- /* Type. */
- debug_type type;
- /* Kind. */
- enum debug_var_kind kind;
- /* Value. */
- bfd_vma val;
-};
-
-/* A list of these structures is used to hold the types for a single
- file. */
-
-struct stab_types
-{
- /* Next set of slots for this file. */
- struct stab_types *next;
- /* Types indexed by type number. */
-#define STAB_TYPES_SLOTS (16)
- debug_type types[STAB_TYPES_SLOTS];
-};
-
-/* We keep a list of undefined tags that we encounter, so that we can
- fill them in if the tag is later defined. */
-
-struct stab_tag
-{
- /* Next undefined tag. */
- struct stab_tag *next;
- /* Tag name. */
- const char *name;
- /* Type kind. */
- enum debug_type_kind kind;
- /* Slot to hold real type when we discover it. If we don't, we fill
- in an undefined tag type. */
- debug_type slot;
- /* Indirect type we have created to point at slot. */
- debug_type type;
-};
-
-static char *savestring PARAMS ((const char *, int));
-static bfd_vma parse_number PARAMS ((const char **, boolean *));
-static void bad_stab PARAMS ((const char *));
-static void warn_stab PARAMS ((const char *, const char *));
-static boolean parse_stab_string
- PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *));
-static debug_type parse_stab_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- debug_type **));
-static boolean parse_stab_type_number
- PARAMS ((const char **, int *));
-static debug_type parse_stab_range_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- const int *));
-static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **));
-static debug_type parse_stab_sun_floating_type
- PARAMS ((PTR, const char **));
-static debug_type parse_stab_enum_type PARAMS ((PTR, const char **));
-static debug_type parse_stab_struct_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean,
- const int *));
-static boolean parse_stab_baseclasses
- PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **));
-static boolean parse_stab_struct_fields
- PARAMS ((PTR, struct stab_handle *, const char **, debug_field **,
- boolean *));
-static boolean parse_stab_cpp_abbrev
- PARAMS ((PTR, struct stab_handle *, const char **, debug_field *));
-static boolean parse_stab_one_struct_field
- PARAMS ((PTR, struct stab_handle *, const char **, const char *,
- debug_field *, boolean *));
-static boolean parse_stab_members
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- const int *, debug_method **));
-static debug_type parse_stab_argtypes
- PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *,
- debug_type, const char *, boolean, boolean, const char **));
-static boolean parse_stab_tilde_field
- PARAMS ((PTR, struct stab_handle *, const char **, const int *,
- debug_type *, boolean *));
-static debug_type parse_stab_array_type
- PARAMS ((PTR, struct stab_handle *, const char **, boolean));
-static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma));
-static const char *pop_bincl PARAMS ((struct stab_handle *));
-static boolean find_excl
- PARAMS ((struct stab_handle *, const char *, bfd_vma));
-static boolean stab_record_variable
- PARAMS ((PTR, struct stab_handle *, const char *, debug_type,
- enum debug_var_kind, bfd_vma));
-static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *));
-static debug_type *stab_find_slot
- PARAMS ((struct stab_handle *, const int *));
-static debug_type stab_find_type
- PARAMS ((PTR, struct stab_handle *, const int *));
-static boolean stab_record_type
- PARAMS ((PTR, struct stab_handle *, const int *, debug_type));
-static debug_type stab_xcoff_builtin_type
- PARAMS ((PTR, struct stab_handle *, int));
-static debug_type stab_find_tagged_type
- PARAMS ((PTR, struct stab_handle *, const char *, int,
- enum debug_type_kind));
-static debug_type *stab_demangle_argtypes
- PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
-
-/* Save a string in memory. */
-
-static char *
-savestring (start, len)
- const char *start;
- int len;
-{
- char *ret;
-
- ret = (char *) xmalloc (len + 1);
- memcpy (ret, start, len);
- ret[len] = '\0';
- return ret;
-}
-
-/* Read a number from a string. */
-
-static bfd_vma
-parse_number (pp, poverflow)
- const char **pp;
- boolean *poverflow;
-{
- unsigned long ul;
- const char *orig;
-
- if (poverflow != NULL)
- *poverflow = false;
-
- orig = *pp;
-
- errno = 0;
- ul = strtoul (*pp, (char **) pp, 0);
- if (ul + 1 != 0 || errno == 0)
- return (bfd_vma) ul;
-
- /* Note that even though strtoul overflowed, it should have set *pp
- to the end of the number, which is where we want it. */
-
- if (sizeof (bfd_vma) > sizeof (unsigned long))
- {
- const char *p;
- boolean neg;
- int base;
- bfd_vma over, lastdig;
- boolean overflow;
- bfd_vma v;
-
- /* Our own version of strtoul, for a bfd_vma. */
-
- p = orig;
-
- neg = false;
- if (*p == '+')
- ++p;
- else if (*p == '-')
- {
- neg = true;
- ++p;
- }
-
- base = 10;
- if (*p == '0')
- {
- if (p[1] == 'x' || p[1] == 'X')
- {
- base = 16;
- p += 2;
- }
- else
- {
- base = 8;
- ++p;
- }
- }
-
- over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
- lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
-
- overflow = false;
- v = 0;
- while (1)
- {
- int d;
-
- d = *p++;
- if (isdigit ((unsigned char) d))
- d -= '0';
- else if (isupper ((unsigned char) d))
- d -= 'A';
- else if (islower ((unsigned char) d))
- d -= 'a';
- else
- break;
-
- if (d >= base)
- break;
-
- if (v > over || (v == over && (bfd_vma) d > lastdig))
- {
- overflow = true;
- break;
- }
- }
-
- if (! overflow)
- {
- if (neg)
- v = - v;
- return v;
- }
- }
-
- /* If we get here, the number is too large to represent in a
- bfd_vma. */
-
- if (poverflow != NULL)
- *poverflow = true;
- else
- warn_stab (orig, "numeric overflow");
-
- return 0;
-}
-
-/* Give an error for a bad stab string. */
-
-static void
-bad_stab (p)
- const char *p;
-{
- fprintf (stderr, "Bad stab: %s\n", p);
-}
-
-/* Warn about something in a stab string. */
-
-static void
-warn_stab (p, err)
- const char *p;
- const char *err;
-{
- fprintf (stderr, "Warning: %s: %s\n", err, p);
-}
-
-/* Create a handle to parse stabs symbols with. */
-
-/*ARGSUSED*/
-PTR
-start_stab (dhandle, abfd, sections, syms, symcount)
- PTR dhandle;
- bfd *abfd;
- boolean sections;
- asymbol **syms;
- long symcount;
-{
- struct stab_handle *ret;
-
- ret = (struct stab_handle *) xmalloc (sizeof *ret);
- memset (ret, 0, sizeof *ret);
- ret->abfd = abfd;
- ret->sections = sections;
- ret->syms = syms;
- ret->symcount = symcount;
- ret->files = 1;
- ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
- ret->file_types[0] = NULL;
- ret->function_end = (bfd_vma) -1;
- return (PTR) ret;
-}
-
-/* When we have processed all the stabs information, we need to go
- through and fill in all the undefined tags. */
-
-boolean
-finish_stab (dhandle, handle)
- PTR dhandle;
- PTR handle;
-{
- struct stab_handle *info = (struct stab_handle *) handle;
- struct stab_tag *st;
-
- if (info->within_function)
- {
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, info->function_end))
- return false;
- info->within_function = false;
- info->function_end = (bfd_vma) -1;
- }
-
- for (st = info->tags; st != NULL; st = st->next)
- {
- enum debug_type_kind kind;
-
- kind = st->kind;
- if (kind == DEBUG_KIND_ILLEGAL)
- kind = DEBUG_KIND_STRUCT;
- st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
- if (st->slot == DEBUG_TYPE_NULL)
- return false;
- }
-
- return true;
-}
-
-/* Handle a single stabs symbol. */
-
-boolean
-parse_stab (dhandle, handle, type, desc, value, string)
- PTR dhandle;
- PTR handle;
- int type;
- int desc;
- bfd_vma value;
- const char *string;
-{
- struct stab_handle *info = (struct stab_handle *) handle;
-
- /* gcc will emit two N_SO strings per compilation unit, one for the
- directory name and one for the file name. We just collect N_SO
- strings as we see them, and start the new compilation unit when
- we see a non N_SO symbol. */
- if (info->so_string != NULL
- && (type != N_SO || *string == '\0' || value != info->so_value))
- {
- if (! debug_set_filename (dhandle, info->so_string))
- return false;
- info->main_filename = info->so_string;
-
- info->gcc_compiled = 0;
- info->n_opt_found = false;
-
- /* Generally, for stabs in the symbol table, the N_LBRAC and
- N_RBRAC symbols are relative to the N_SO symbol value. */
- if (! info->sections)
- info->file_start_offset = info->so_value;
-
- /* We need to reset the mapping from type numbers to types. We
- can't free the old mapping, because of the use of
- debug_make_indirect_type. */
- info->files = 1;
- info->file_types = ((struct stab_types **)
- xmalloc (sizeof *info->file_types));
- info->file_types[0] = NULL;
-
- info->so_string = NULL;
-
- /* Now process whatever type we just got. */
- }
-
- switch (type)
- {
- case N_FN:
- case N_FN_SEQ:
- break;
-
- case N_LBRAC:
- /* Ignore extra outermost context from SunPRO cc and acc. */
- if (info->n_opt_found && desc == 1)
- break;
-
- if (! info->within_function)
- {
- fprintf (stderr, "N_LBRAC not within function\n");
- return false;
- }
-
- /* Start an inner lexical block. */
- if (! debug_start_block (dhandle,
- (value
- + info->file_start_offset
- + info->function_start_offset)))
- return false;
-
- /* Emit any pending variable definitions. */
- if (! stab_emit_pending_vars (dhandle, info))
- return false;
-
- ++info->block_depth;
- break;
-
- case N_RBRAC:
- /* Ignore extra outermost context from SunPRO cc and acc. */
- if (info->n_opt_found && desc == 1)
- break;
-
- /* We shouldn't have any pending variable definitions here, but,
- if we do, we probably need to emit them before closing the
- block. */
- if (! stab_emit_pending_vars (dhandle, info))
- return false;
-
- /* End an inner lexical block. */
- if (! debug_end_block (dhandle,
- (value
- + info->file_start_offset
- + info->function_start_offset)))
- return false;
-
- --info->block_depth;
- if (info->block_depth < 0)
- {
- fprintf (stderr, "Too many N_RBRACs\n");
- return false;
- }
- break;
-
- case N_SO:
- /* This always ends a function. */
- if (info->within_function)
- {
- bfd_vma endval;
-
- endval = value;
- if (*string != '\0'
- && info->function_end != (bfd_vma) -1
- && info->function_end < endval)
- endval = info->function_end;
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, endval))
- return false;
- info->within_function = false;
- info->function_end = (bfd_vma) -1;
- }
-
- /* An empty string is emitted by gcc at the end of a compilation
- unit. */
- if (*string == '\0')
- return true;
-
- /* Just accumulate strings until we see a non N_SO symbol. If
- the string starts with '/', we discard the previously
- accumulated strings. */
- if (info->so_string == NULL)
- info->so_string = xstrdup (string);
- else
- {
- char *f;
-
- f = info->so_string;
- if (*string == '/')
- info->so_string = xstrdup (string);
- else
- info->so_string = concat (info->so_string, string,
- (const char *) NULL);
- free (f);
- }
-
- info->so_value = value;
-
- break;
-
- case N_SOL:
- /* Start an include file. */
- if (! debug_start_source (dhandle, string))
- return false;
- break;
-
- case N_BINCL:
- /* Start an include file which may be replaced. */
- push_bincl (info, string, value);
- if (! debug_start_source (dhandle, string))
- return false;
- break;
-
- case N_EINCL:
- /* End an N_BINCL include. */
- if (! debug_start_source (dhandle, pop_bincl (info)))
- return false;
- break;
-
- case N_EXCL:
- /* This is a duplicate of a header file named by N_BINCL which
- was eliminated by the linker. */
- if (! find_excl (info, string, value))
- return false;
- break;
-
- case N_SLINE:
- if (! debug_record_line (dhandle, desc,
- value + info->function_start_offset))
- return false;
- break;
-
- case N_BCOMM:
- if (! debug_start_common_block (dhandle, string))
- return false;
- break;
-
- case N_ECOMM:
- if (! debug_end_common_block (dhandle, string))
- return false;
- break;
-
- case N_FUN:
- if (*string == '\0')
- {
- if (info->within_function)
- {
- /* This always marks the end of a function; we don't
- need to worry about info->function_end. */
- if (info->sections)
- value += info->function_start_offset;
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, value))
- return false;
- info->within_function = false;
- info->function_end = (bfd_vma) -1;
- }
- break;
- }
-
- /* A const static symbol in the .text section will have an N_FUN
- entry. We need to use these to mark the end of the function,
- in case we are looking at gcc output before it was changed to
- always emit an empty N_FUN. We can't call debug_end_function
- here, because it might be a local static symbol. */
- if (info->within_function
- && (info->function_end == (bfd_vma) -1
- || value < info->function_end))
- info->function_end = value;
-
- /* Fall through. */
- /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
- symbols, and if it does not start with :S, gdb relocates the
- value to the start of the section. gcc always seems to use
- :S, so we don't worry about this. */
- /* Fall through. */
- default:
- {
- const char *colon;
-
- colon = strchr (string, ':');
- if (colon != NULL
- && (colon[1] == 'f' || colon[1] == 'F'))
- {
- if (info->within_function)
- {
- bfd_vma endval;
-
- endval = value;
- if (info->function_end != (bfd_vma) -1
- && info->function_end < endval)
- endval = info->function_end;
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, endval))
- return false;
- info->function_end = (bfd_vma) -1;
- }
- /* For stabs in sections, line numbers and block addresses
- are offsets from the start of the function. */
- if (info->sections)
- info->function_start_offset = value;
- info->within_function = true;
- }
-
- if (! parse_stab_string (dhandle, info, type, desc, value, string))
- return false;
- }
- break;
-
- case N_OPT:
- if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
- info->gcc_compiled = 2;
- else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
- info->gcc_compiled = 1;
- else
- info->n_opt_found = true;
- break;
-
- case N_OBJ:
- case N_ENDM:
- case N_MAIN:
- break;
- }
-
- return true;
-}
-
-/* Parse the stabs string. */
-
-static boolean
-parse_stab_string (dhandle, info, stabtype, desc, value, string)
- PTR dhandle;
- struct stab_handle *info;
- int stabtype;
- int desc;
- bfd_vma value;
- const char *string;
-{
- const char *p;
- char *name;
- int type;
- debug_type dtype;
- boolean synonym;
- unsigned int lineno;
- debug_type *slot;
-
- p = strchr (string, ':');
- if (p == NULL)
- return true;
-
- while (p[1] == ':')
- {
- p += 2;
- p = strchr (p, ':');
- if (p == NULL)
- {
- bad_stab (string);
- return false;
- }
- }
-
- /* GCC 2.x puts the line number in desc. SunOS apparently puts in
- the number of bytes occupied by a type or object, which we
- ignore. */
- if (info->gcc_compiled >= 2)
- lineno = desc;
- else
- lineno = 0;
-
- /* FIXME: Sometimes the special C++ names start with '.'. */
- name = NULL;
- if (string[0] == '$')
- {
- switch (string[1])
- {
- case 't':
- name = "this";
- break;
- case 'v':
- /* Was: name = "vptr"; */
- break;
- case 'e':
- name = "eh_throw";
- break;
- case '_':
- /* This was an anonymous type that was never fixed up. */
- break;
- case 'X':
- /* SunPRO (3.0 at least) static variable encoding. */
- break;
- default:
- warn_stab (string, "unknown C++ encoded name");
- break;
- }
- }
-
- if (name == NULL)
- {
- if (p == string || (string[0] == ' ' && p == string + 1))
- name = NULL;
- else
- name = savestring (string, p - string);
- }
-
- ++p;
- if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
- type = 'l';
- else
- type = *p++;
-
- switch (type)
- {
- case 'c':
- /* c is a special case, not followed by a type-number.
- SYMBOL:c=iVALUE for an integer constant symbol.
- SYMBOL:c=rVALUE for a floating constant symbol.
- SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
- e.g. "b:c=e6,0" for "const b = blob1"
- (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
- if (*p != '=')
- {
- bad_stab (string);
- return false;
- }
- ++p;
- switch (*p++)
- {
- case 'r':
- /* Floating point constant. */
- if (! debug_record_float_const (dhandle, name, atof (p)))
- return false;
- break;
- case 'i':
- /* Integer constant. */
- /* Defining integer constants this way is kind of silly,
- since 'e' constants allows the compiler to give not only
- the value, but the type as well. C has at least int,
- long, unsigned int, and long long as constant types;
- other languages probably should have at least unsigned as
- well as signed constants. */
- if (! debug_record_int_const (dhandle, name, atoi (p)))
- return false;
- break;
- case 'e':
- /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
- can be represented as integral.
- e.g. "b:c=e6,0" for "const b = blob1"
- (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- &p, (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (*p != ',')
- {
- bad_stab (string);
- return false;
- }
- if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
- return false;
- break;
- default:
- bad_stab (string);
- return false;
- }
-
- break;
-
- case 'C':
- /* The name of a caught exception. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- &p, (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_label (dhandle, name, dtype, value))
- return false;
- break;
-
- case 'f':
- case 'F':
- /* A function definition. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
- return false;
-
- /* Sun acc puts declared types of arguments here. We don't care
- about their actual types (FIXME -- we should remember the whole
- function prototype), but the list may define some new types
- that we have to remember, so we must scan it now. */
- while (*p == ';')
- {
- ++p;
- if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL)
- == DEBUG_TYPE_NULL)
- return false;
- }
-
- break;
-
- case 'G':
- {
- char leading;
- long c;
- asymbol **ps;
-
- /* A global symbol. The value must be extracted from the
- symbol table. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- leading = bfd_get_symbol_leading_char (info->abfd);
- for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
- {
- const char *n;
-
- n = bfd_asymbol_name (*ps);
- if (leading != '\0' && *n == leading)
- ++n;
- if (*n == *name && strcmp (n, name) == 0)
- break;
- }
- if (c > 0)
- value = bfd_asymbol_value (*ps);
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
- value))
- return false;
- }
- break;
-
- /* This case is faked by a conditional above, when there is no
- code letter in the dbx data. Dbx data never actually
- contains 'l'. */
- case 'l':
- case 's':
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
- value))
- return false;
- break;
-
- case 'p':
- /* A function parameter. */
- if (*p != 'F')
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- else
- {
- /* pF is a two-letter code that means a function parameter in
- Fortran. The type-number specifies the type of the return
- value. Translate it into a pointer-to-function type. */
- ++p;
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype != DEBUG_TYPE_NULL)
- {
- debug_type ftype;
-
- ftype = debug_make_function_type (dhandle, dtype,
- (debug_type *) NULL, false);
- dtype = debug_make_pointer_type (dhandle, ftype);
- }
- }
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
- value))
- return false;
-
- /* FIXME: At this point gdb considers rearranging the parameter
- address on a big endian machine if it is smaller than an int.
- We have no way to do that, since we don't really know much
- about the target. */
-
- break;
-
- case 'P':
- if (stabtype == N_FUN)
- {
- /* Prototype of a function referenced by this file. */
- while (*p == ';')
- {
- ++p;
- if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL)
- == DEBUG_TYPE_NULL)
- return false;
- }
- break;
- }
- /* Fall through. */
- case 'R':
- /* Parameter which is in a register. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
- value))
- return false;
- break;
-
- case 'r':
- /* Register variable (either global or local). */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
- value))
- return false;
-
- /* FIXME: At this point gdb checks to combine pairs of 'p' and
- 'r' stabs into a single 'P' stab. */
-
- break;
-
- case 'S':
- /* Static symbol at top level of file */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
- value))
- return false;
- break;
-
- case 't':
- /* A typedef. */
- dtype = parse_stab_type (dhandle, info, name, &p, &slot);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (name == NULL)
- {
- /* A nameless type. Nothing to do. */
- return true;
- }
-
- dtype = debug_name_type (dhandle, name, dtype);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
-
- if (slot != NULL)
- *slot = dtype;
-
- break;
-
- case 'T':
- /* Struct, union, or enum tag. For GNU C++, this can be be followed
- by 't' which means we are typedef'ing it as well. */
- if (*p != 't')
- {
- synonym = false;
- /* FIXME: gdb sets synonym to true if the current language
- is C++. */
- }
- else
- {
- synonym = true;
- ++p;
- }
-
- dtype = parse_stab_type (dhandle, info, name, &p, &slot);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (name == NULL)
- return true;
-
- dtype = debug_tag_type (dhandle, name, dtype);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (slot != NULL)
- *slot = dtype;
-
- /* See if we have a cross reference to this tag which we can now
- fill in. */
- {
- register struct stab_tag **pst;
-
- for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
- {
- if ((*pst)->name[0] == name[0]
- && strcmp ((*pst)->name, name) == 0)
- {
- (*pst)->slot = dtype;
- *pst = (*pst)->next;
- break;
- }
- }
- }
-
- if (synonym)
- {
- dtype = debug_name_type (dhandle, name, dtype);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
-
- if (slot != NULL)
- *slot = dtype;
- }
-
- break;
-
- case 'V':
- /* Static symbol of local scope */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- /* FIXME: gdb checks os9k_stabs here. */
- if (! stab_record_variable (dhandle, info, name, dtype,
- DEBUG_LOCAL_STATIC, value))
- return false;
- break;
-
- case 'v':
- /* Reference parameter. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
- value))
- return false;
- break;
-
- case 'a':
- /* Reference parameter which is in a register. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
- value))
- return false;
- break;
-
- case 'X':
- /* This is used by Sun FORTRAN for "function result value".
- Sun claims ("dbx and dbxtool interfaces", 2nd ed)
- that Pascal uses it too, but when I tried it Pascal used
- "x:3" (local symbol) instead. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
- value))
- return false;
- break;
-
- default:
- bad_stab (string);
- return false;
- }
-
- /* FIXME: gdb converts structure values to structure pointers in a
- couple of cases, depending upon the target. */
-
- return true;
-}
-
-/* Parse a stabs type. The typename argument is non-NULL if this is a
- typedef or a tag definition. The pp argument points to the stab
- string, and is updated. The slotp argument points to a place to
- store the slot used if the type is being defined. */
-
-static debug_type
-parse_stab_type (dhandle, info, typename, pp, slotp)
- PTR dhandle;
- struct stab_handle *info;
- const char *typename;
- const char **pp;
- debug_type **slotp;
-{
- const char *orig;
- int typenums[2];
- int size;
- boolean stringp;
- int descriptor;
- debug_type dtype;
-
- if (slotp != NULL)
- *slotp = NULL;
-
- orig = *pp;
-
- size = -1;
- stringp = false;
-
- /* Read type number if present. The type number may be omitted.
- for instance in a two-dimensional array declared with type
- "ar1;1;10;ar1;1;10;4". */
- if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
- {
- /* 'typenums=' not present, type is anonymous. Read and return
- the definition, but don't put it in the type vector. */
- typenums[0] = typenums[1] = -1;
- }
- else
- {
- if (! parse_stab_type_number (pp, typenums))
- return DEBUG_TYPE_NULL;
-
- if (**pp != '=')
- {
- /* Type is not being defined here. Either it already
- exists, or this is a forward reference to it. */
- return stab_find_type (dhandle, info, typenums);
- }
-
- /* Only set the slot if the type is being defined. This means
- that the mapping from type numbers to types will only record
- the name of the typedef which defines a type. If we don't do
- this, then something like
- typedef int foo;
- int i;
- will record that i is of type foo. Unfortunately, stabs
- information is ambiguous about variable types. For this code,
- typedef int foo;
- int i;
- foo j;
- the stabs information records both i and j as having the same
- type. This could be fixed by patching the compiler. */
- if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
- *slotp = stab_find_slot (info, typenums);
-
- /* Type is being defined here. */
- /* Skip the '='. */
- ++*pp;
-
- while (**pp == '@')
- {
- const char *p = *pp + 1;
- const char *attr;
-
- if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
- {
- /* Member type. */
- break;
- }
-
- /* Type attributes. */
- attr = p;
-
- for (; *p != ';'; ++p)
- {
- if (*p == '\0')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- }
- *pp = p + 1;
-
- switch (*attr)
- {
- case 's':
- size = atoi (attr + 1);
- if (size <= 0)
- size = -1;
- break;
-
- case 'S':
- stringp = true;
- break;
-
- default:
- /* Ignore unrecognized type attributes, so future
- compilers can invent new ones. */
- break;
- }
- }
- }
-
- descriptor = **pp;
- ++*pp;
-
- switch (descriptor)
- {
- case 'x':
- {
- enum debug_type_kind code;
- const char *q1, *q2, *p;
-
- /* A cross reference to another type. */
-
- switch (**pp)
- {
- case 's':
- code = DEBUG_KIND_STRUCT;
- break;
- case 'u':
- code = DEBUG_KIND_UNION;
- break;
- case 'e':
- code = DEBUG_KIND_ENUM;
- break;
- default:
- /* Complain and keep going, so compilers can invent new
- cross-reference types. */
- warn_stab (orig, "unrecognized cross reference type");
- code = DEBUG_KIND_STRUCT;
- break;
- }
- ++*pp;
-
- q1 = strchr (*pp, '<');
- p = strchr (*pp, ':');
- if (p == NULL)
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- while (q1 != NULL && p > q1 && p[1] == ':')
- {
- q2 = strchr (q1, '>');
- if (q2 == NULL || q2 < p)
- break;
- p += 2;
- p = strchr (p, ':');
- if (p == NULL)
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- }
-
- dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
-
- *pp = p + 1;
- }
- break;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '(':
- {
- const char *hold;
- int xtypenums[2];
-
- /* This type is defined as another type. */
-
- (*pp)--;
- hold = *pp;
-
- /* Peek ahead at the number to detect void. */
- if (! parse_stab_type_number (pp, xtypenums))
- return DEBUG_TYPE_NULL;
-
- if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
- {
- /* This type is being defined as itself, which means that
- it is void. */
- dtype = debug_make_void_type (dhandle);
- }
- else
- {
- *pp = hold;
-
- /* Go back to the number and have parse_stab_type get it.
- This means that we can deal with something like
- t(1,2)=(3,4)=... which the Lucid compiler uses. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- }
-
- if (typenums[0] != -1)
- {
- if (! stab_record_type (dhandle, info, typenums, dtype))
- return DEBUG_TYPE_NULL;
- }
-
- break;
- }
-
- case '*':
- dtype = debug_make_pointer_type (dhandle,
- parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL));
- break;
-
- case '&':
- /* Reference to another type. */
- dtype = (debug_make_reference_type
- (dhandle,
- parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL)));
- break;
-
- case 'f':
- /* Function returning another type. */
- /* FIXME: gdb checks os9k_stabs here. */
- dtype = (debug_make_function_type
- (dhandle,
- parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL),
- (debug_type *) NULL, false));
- break;
-
- case 'k':
- /* Const qualifier on some type (Sun). */
- /* FIXME: gdb accepts 'c' here if os9k_stabs. */
- dtype = debug_make_const_type (dhandle,
- parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL));
- break;
-
- case 'B':
- /* Volatile qual on some type (Sun). */
- /* FIXME: gdb accepts 'i' here if os9k_stabs. */
- dtype = (debug_make_volatile_type
- (dhandle,
- parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL)));
- break;
-
- case '@':
- /* Offset (class & variable) type. This is used for a pointer
- relative to an object. */
- {
- debug_type domain;
- debug_type memtype;
-
- /* Member type. */
-
- domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (domain == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (memtype == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- dtype = debug_make_offset_type (dhandle, domain, memtype);
- }
- break;
-
- case '#':
- /* Method (class & fn) type. */
- if (**pp == '#')
- {
- debug_type return_type;
-
- ++*pp;
- return_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (return_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
- dtype = debug_make_method_type (dhandle, return_type,
- DEBUG_TYPE_NULL,
- (debug_type *) NULL, false);
- }
- else
- {
- debug_type domain;
- debug_type return_type;
- debug_type *args;
- unsigned int n;
- unsigned int alloc;
- boolean varargs;
-
- domain = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (domain == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- return_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (return_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- alloc = 10;
- args = (debug_type *) xmalloc (alloc * sizeof *args);
- n = 0;
- while (**pp != ';')
- {
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (n + 1 >= alloc)
- {
- alloc += 10;
- args = ((debug_type *)
- xrealloc ((PTR) args, alloc * sizeof *args));
- }
-
- args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (args[n] == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- ++n;
- }
- ++*pp;
-
- /* If the last type is not void, then this function takes a
- variable number of arguments. Otherwise, we must strip
- the void type. */
- if (n == 0
- || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
- varargs = true;
- else
- {
- --n;
- varargs = false;
- }
-
- args[n] = DEBUG_TYPE_NULL;
-
- dtype = debug_make_method_type (dhandle, return_type, domain, args,
- varargs);
- }
- break;
-
- case 'r':
- /* Range type. */
- dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
- break;
-
- case 'b':
- /* FIXME: gdb checks os9k_stabs here. */
- /* Sun ACC builtin int type. */
- dtype = parse_stab_sun_builtin_type (dhandle, pp);
- break;
-
- case 'R':
- /* Sun ACC builtin float type. */
- dtype = parse_stab_sun_floating_type (dhandle, pp);
- break;
-
- case 'e':
- /* Enumeration type. */
- dtype = parse_stab_enum_type (dhandle, pp);
- break;
-
- case 's':
- case 'u':
- /* Struct or union type. */
- dtype = parse_stab_struct_type (dhandle, info, typename, pp,
- descriptor == 's', typenums);
- break;
-
- case 'a':
- /* Array type. */
- if (**pp != 'r')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- dtype = parse_stab_array_type (dhandle, info, pp, stringp);
- break;
-
- case 'S':
- dtype = debug_make_set_type (dhandle,
- parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL),
- stringp);
- break;
-
- default:
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- if (dtype == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (typenums[0] != -1)
- {
- if (! stab_record_type (dhandle, info, typenums, dtype))
- return DEBUG_TYPE_NULL;
- }
-
- if (size != -1)
- {
- if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
- return DEBUG_TYPE_NULL;
- }
-
- return dtype;
-}
-
-/* Read a number by which a type is referred to in dbx data, or
- perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a
- single number N is equivalent to (0,N). Return the two numbers by
- storing them in the vector TYPENUMS. */
-
-static boolean
-parse_stab_type_number (pp, typenums)
- const char **pp;
- int *typenums;
-{
- const char *orig;
-
- orig = *pp;
-
- if (**pp != '(')
- {
- typenums[0] = 0;
- typenums[1] = (int) parse_number (pp, (boolean *) NULL);
- }
- else
- {
- ++*pp;
- typenums[0] = (int) parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- typenums[1] = (int) parse_number (pp, (boolean *) NULL);
- if (**pp != ')')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- }
-
- return true;
-}
-
-/* Parse a range type. */
-
-static debug_type
-parse_stab_range_type (dhandle, info, typename, pp, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const char *typename;
- const char **pp;
- const int *typenums;
-{
- const char *orig;
- int rangenums[2];
- boolean self_subrange;
- debug_type index_type;
- const char *s2, *s3;
- bfd_signed_vma n2, n3;
- boolean ov2, ov3;
-
- orig = *pp;
-
- index_type = DEBUG_TYPE_NULL;
-
- /* First comes a type we are a subrange of.
- In C it is usually 0, 1 or the type being defined. */
- if (! parse_stab_type_number (pp, rangenums))
- return DEBUG_TYPE_NULL;
-
- self_subrange = (rangenums[0] == typenums[0]
- && rangenums[1] == typenums[1]);
-
- if (**pp == '=')
- {
- *pp = orig;
- index_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (index_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- }
-
- if (**pp == ';')
- ++*pp;
-
- /* The remaining two operands are usually lower and upper bounds of
- the range. But in some special cases they mean something else. */
- s2 = *pp;
- n2 = parse_number (pp, &ov2);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- s3 = *pp;
- n3 = parse_number (pp, &ov3);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (ov2 || ov3)
- {
- /* gcc will emit range stabs for long long types. Handle this
- as a special case. FIXME: This needs to be more general. */
-#define LLLOW "01000000000000000000000;"
-#define LLHIGH "0777777777777777777777;"
-#define ULLHIGH "01777777777777777777777;"
- if (index_type == DEBUG_TYPE_NULL)
- {
- if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
- && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
- return debug_make_int_type (dhandle, 8, false);
- if (! ov2
- && n2 == 0
- && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
- return debug_make_int_type (dhandle, 8, true);
- }
-
- warn_stab (orig, "numeric overflow");
- }
-
- if (index_type == DEBUG_TYPE_NULL)
- {
- /* A type defined as a subrange of itself, with both bounds 0,
- is void. */
- if (self_subrange && n2 == 0 && n3 == 0)
- return debug_make_void_type (dhandle);
-
- /* A type defined as a subrange of itself, with n2 positive and
- n3 zero, is a complex type, and n2 is the number of bytes. */
- if (self_subrange && n3 == 0 && n2 > 0)
- return debug_make_complex_type (dhandle, n2);
-
- /* If n3 is zero and n2 is positive, this is a floating point
- type, and n2 is the number of bytes. */
- if (n3 == 0 && n2 > 0)
- return debug_make_float_type (dhandle, n2);
-
- /* If the upper bound is -1, this is an unsigned int. */
- if (n2 == 0 && n3 == -1)
- {
- /* When gcc is used with -gstabs, but not -gstabs+, it will emit
- long long int:t6=r1;0;-1;
- long long unsigned int:t7=r1;0;-1;
- We hack here to handle this reasonably. */
- if (typename != NULL)
- {
- if (strcmp (typename, "long long int") == 0)
- return debug_make_int_type (dhandle, 8, false);
- else if (strcmp (typename, "long long unsigned int") == 0)
- return debug_make_int_type (dhandle, 8, true);
- }
- /* FIXME: The size here really depends upon the target. */
- return debug_make_int_type (dhandle, 4, true);
- }
-
- /* A range of 0 to 127 is char. */
- if (self_subrange && n2 == 0 && n3 == 127)
- return debug_make_int_type (dhandle, 1, false);
-
- /* FIXME: gdb checks for the language CHILL here. */
-
- if (n2 == 0)
- {
- if (n3 < 0)
- return debug_make_int_type (dhandle, - n3, true);
- else if (n3 == 0xff)
- return debug_make_int_type (dhandle, 1, true);
- else if (n3 == 0xffff)
- return debug_make_int_type (dhandle, 2, true);
- /* -1 is used for the upper bound of (4 byte) "unsigned int"
- and "unsigned long", and we already checked for that, so
- don't need to test for it here. */
- }
- else if (n3 == 0
- && n2 < 0
- && (self_subrange || n2 == -8))
- return debug_make_int_type (dhandle, - n2, true);
- else if (n2 == - n3 - 1)
- {
- if (n3 == 0x7f)
- return debug_make_int_type (dhandle, 1, false);
- else if (n3 == 0x7fff)
- return debug_make_int_type (dhandle, 2, false);
- else if (n3 == 0x7fffffff)
- return debug_make_int_type (dhandle, 4, false);
- }
- }
-
- /* At this point I don't have the faintest idea how to deal with a
- self_subrange type; I'm going to assume that this is used as an
- idiom, and that all of them are special cases. So . . . */
- if (self_subrange)
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- index_type = stab_find_type (dhandle, info, rangenums);
- if (index_type == DEBUG_TYPE_NULL)
- {
- /* Does this actually ever happen? Is that why we are worrying
- about dealing with it rather than just calling error_type? */
- warn_stab (orig, "missing index type");
- index_type = debug_make_int_type (dhandle, 4, false);
- }
-
- return debug_make_range_type (dhandle, index_type, n2, n3);
-}
-
-/* Sun's ACC uses a somewhat saner method for specifying the builtin
- typedefs in every file (for int, long, etc):
-
- type = b <signed> <width>; <offset>; <nbits>
- signed = u or s. Possible c in addition to u or s (for char?).
- offset = offset from high order bit to start bit of type.
- width is # bytes in object of this type, nbits is # bits in type.
-
- The width/offset stuff appears to be for small objects stored in
- larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
- FIXME. */
-
-static debug_type
-parse_stab_sun_builtin_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
-{
- const char *orig;
- boolean unsignedp;
- bfd_vma bits;
-
- orig = *pp;
-
- switch (**pp)
- {
- case 's':
- unsignedp = false;
- break;
- case 'u':
- unsignedp = true;
- break;
- default:
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- /* For some odd reason, all forms of char put a c here. This is strange
- because no other type has this honor. We can safely ignore this because
- we actually determine 'char'acterness by the number of bits specified in
- the descriptor. */
- if (**pp == 'c')
- ++*pp;
-
- /* The first number appears to be the number of bytes occupied
- by this type, except that unsigned short is 4 instead of 2.
- Since this information is redundant with the third number,
- we will ignore it. */
- (void) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- /* The second number is always 0, so ignore it too. */
- (void) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- /* The third number is the number of bits for this type. */
- bits = parse_number (pp, (boolean *) NULL);
-
- /* The type *should* end with a semicolon. If it are embedded
- in a larger type the semicolon may be the only way to know where
- the type ends. If this type is at the end of the stabstring we
- can deal with the omitted semicolon (but we don't have to like
- it). Don't bother to complain(), Sun's compiler omits the semicolon
- for "void". */
- if (**pp == ';')
- ++*pp;
-
- if (bits == 0)
- return debug_make_void_type (dhandle);
-
- return debug_make_int_type (dhandle, bits / 8, unsignedp);
-}
-
-/* Parse a builtin floating type generated by the Sun compiler. */
-
-static debug_type
-parse_stab_sun_floating_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
-{
- const char *orig;
- bfd_vma details;
- bfd_vma bytes;
-
- orig = *pp;
-
- /* The first number has more details about the type, for example
- FN_COMPLEX. */
- details = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- /* The second number is the number of bytes occupied by this type */
- bytes = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- if (details == NF_COMPLEX
- || details == NF_COMPLEX16
- || details == NF_COMPLEX32)
- return debug_make_complex_type (dhandle, bytes);
-
- return debug_make_float_type (dhandle, bytes);
-}
-
-/* Handle an enum type. */
-
-static debug_type
-parse_stab_enum_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
-{
- const char *orig;
- const char **names;
- bfd_signed_vma *values;
- unsigned int n;
- unsigned int alloc;
-
- orig = *pp;
-
- /* FIXME: gdb checks os9k_stabs here. */
-
- /* The aix4 compiler emits an extra field before the enum members;
- my guess is it's a type of some sort. Just ignore it. */
- if (**pp == '-')
- {
- while (**pp != ':')
- ++*pp;
- ++*pp;
- }
-
- /* Read the value-names and their values.
- The input syntax is NAME:VALUE,NAME:VALUE, and so on.
- A semicolon or comma instead of a NAME means the end. */
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);
- n = 0;
- while (**pp != '\0' && **pp != ';' && **pp != ',')
- {
- const char *p;
- char *name;
- bfd_signed_vma val;
-
- p = *pp;
- while (*p != ':')
- ++p;
-
- name = savestring (*pp, p - *pp);
-
- *pp = p + 1;
- val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (n + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc ((PTR) names, alloc * sizeof *names));
- values = ((bfd_signed_vma *)
- xrealloc ((PTR) values, alloc * sizeof *values));
- }
-
- names[n] = name;
- values[n] = val;
- ++n;
- }
-
- names[n] = NULL;
- values[n] = 0;
-
- if (**pp == ';')
- ++*pp;
-
- return debug_make_enum_type (dhandle, names, values);
-}
-
-/* Read the description of a structure (or union type) and return an object
- describing the type.
-
- PP points to a character pointer that points to the next unconsumed token
- in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
- *PP will point to "4a:1,0,32;;". */
-
-static debug_type
-parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const char *tagname;
- const char **pp;
- boolean structp;
- const int *typenums;
-{
- const char *orig;
- bfd_vma size;
- debug_baseclass *baseclasses;
- debug_field *fields;
- boolean statics;
- debug_method *methods;
- debug_type vptrbase;
- boolean ownvptr;
-
- orig = *pp;
-
- /* Get the size. */
- size = parse_number (pp, (boolean *) NULL);
-
- /* Get the other information. */
- if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
- || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
- || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
- || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
- &ownvptr))
- return DEBUG_TYPE_NULL;
-
- if (! statics
- && baseclasses == NULL
- && methods == NULL
- && vptrbase == DEBUG_TYPE_NULL
- && ! ownvptr)
- return debug_make_struct_type (dhandle, structp, size, fields);
-
- return debug_make_object_type (dhandle, structp, size, fields, baseclasses,
- methods, vptrbase, ownvptr);
-}
-
-/* The stabs for C++ derived classes contain baseclass information which
- is marked by a '!' character after the total size. This function is
- called when we encounter the baseclass marker, and slurps up all the
- baseclass information.
-
- Immediately following the '!' marker is the number of base classes that
- the class is derived from, followed by information for each base class.
- For each base class, there are two visibility specifiers, a bit offset
- to the base class information within the derived class, a reference to
- the type for the base class, and a terminating semicolon.
-
- A typical example, with two base classes, would be "!2,020,19;0264,21;".
- ^^ ^ ^ ^ ^ ^ ^
- Baseclass information marker __________________|| | | | | | |
- Number of baseclasses __________________________| | | | | | |
- Visibility specifiers (2) ________________________| | | | | |
- Offset in bits from start of class _________________| | | | |
- Type number for base class ___________________________| | | |
- Visibility specifiers (2) _______________________________| | |
- Offset in bits from start of class ________________________| |
- Type number of base class ____________________________________|
-
- Return true for success, false for failure. */
-
-static boolean
-parse_stab_baseclasses (dhandle, info, pp, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_baseclass **retp;
-{
- const char *orig;
- unsigned int c, i;
- debug_baseclass *classes;
-
- *retp = NULL;
-
- orig = *pp;
-
- if (**pp != '!')
- {
- /* No base classes. */
- return true;
- }
- ++*pp;
-
- c = (unsigned int) parse_number (pp, (boolean *) NULL);
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp));
-
- for (i = 0; i < c; i++)
- {
- boolean virtual;
- enum debug_visibility visibility;
- bfd_vma bitpos;
- debug_type type;
-
- switch (**pp)
- {
- case '0':
- virtual = false;
- break;
- case '1':
- virtual = true;
- break;
- default:
- warn_stab (orig, "unknown virtual character for baseclass");
- virtual = false;
- break;
- }
- ++*pp;
-
- switch (**pp)
- {
- case '0':
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
- case '1':
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- case '2':
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- default:
- warn_stab (orig, "unknown visibility character for baseclass");
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- }
- ++*pp;
-
- /* The remaining value is the bit offset of the portion of the
- object corresponding to this baseclass. Always zero in the
- absence of multiple inheritance. */
- bitpos = parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
- visibility);
- if (classes[i] == DEBUG_BASECLASS_NULL)
- return false;
-
- if (**pp != ';')
- return false;
- ++*pp;
- }
-
- classes[i] = DEBUG_BASECLASS_NULL;
-
- *retp = classes;
-
- return true;
-}
-
-/* Read struct or class data fields. They have the form:
-
- NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
-
- At the end, we see a semicolon instead of a field.
-
- In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
- a static field.
-
- The optional VISIBILITY is one of:
-
- '/0' (VISIBILITY_PRIVATE)
- '/1' (VISIBILITY_PROTECTED)
- '/2' (VISIBILITY_PUBLIC)
- '/9' (VISIBILITY_IGNORE)
-
- or nothing, for C style fields with public visibility.
-
- Returns 1 for success, 0 for failure. */
-
-static boolean
-parse_stab_struct_fields (dhandle, info, pp, retp, staticsp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_field **retp;
- boolean *staticsp;
-{
- const char *orig;
- const char *p;
- debug_field *fields;
- unsigned int c;
- unsigned int alloc;
-
- *retp = NULL;
- *staticsp = false;
-
- orig = *pp;
-
- c = 0;
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- while (**pp != ';')
- {
- /* FIXME: gdb checks os9k_stabs here. */
-
- p = *pp;
-
- /* Add 1 to c to leave room for NULL pointer at end. */
- if (c + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc ((PTR) fields, alloc * sizeof *fields));
- }
-
- /* If it starts with CPLUS_MARKER it is a special abbreviation,
- unless the CPLUS_MARKER is followed by an underscore, in
- which case it is just the name of an anonymous type, which we
- should handle like any other type name. We accept either '$'
- or '.', because a field name can never contain one of these
- characters except as a CPLUS_MARKER. */
-
- if ((*p == '$' || *p == '.') && p[1] != '_')
- {
- ++*pp;
- if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
- return false;
- ++c;
- continue;
- }
-
- /* Look for the ':' that separates the field name from the field
- values. Data members are delimited by a single ':', while member
- functions are delimited by a pair of ':'s. When we hit the member
- functions (if any), terminate scan loop and return. */
-
- p = strchr (p, ':');
- if (p == NULL)
- {
- bad_stab (orig);
- return false;
- }
-
- if (p[1] == ':')
- break;
-
- if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
- staticsp))
- return false;
-
- ++c;
- }
-
- fields[c] = DEBUG_FIELD_NULL;
-
- *retp = fields;
-
- return true;
-}
-
-/* Special GNU C++ name. */
-
-static boolean
-parse_stab_cpp_abbrev (dhandle, info, pp, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_field *retp;
-{
- const char *orig;
- int cpp_abbrev;
- debug_type context;
- const char *name;
- const char *typename;
- debug_type type;
- bfd_vma bitpos;
-
- *retp = DEBUG_FIELD_NULL;
-
- orig = *pp;
-
- if (**pp != 'v')
- {
- bad_stab (*pp);
- return false;
- }
- ++*pp;
-
- cpp_abbrev = **pp;
- ++*pp;
-
- /* At this point, *pp points to something like "22:23=*22...", where
- the type number before the ':' is the "context" and everything
- after is a regular type definition. Lookup the type, find it's
- name, and construct the field name. */
-
- context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (context == DEBUG_TYPE_NULL)
- return false;
-
- switch (cpp_abbrev)
- {
- case 'f':
- /* $vf -- a virtual function table pointer. */
- name = "_vptr$";
- break;
- case 'b':
- /* $vb -- a virtual bsomethingorother */
- typename = debug_get_type_name (dhandle, context);
- if (typename == NULL)
- {
- warn_stab (orig, "unnamed $vb type");
- typename = "FOO";
- }
- name = concat ("_vb$", typename, (const char *) NULL);
- break;
- default:
- warn_stab (orig, "unrecognized C++ abbreviation");
- name = "INVALID_CPLUSPLUS_ABBREV";
- break;
- }
-
- if (**pp != ':')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- bitpos = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- *retp = debug_make_field (dhandle, name, type, bitpos, 0,
- DEBUG_VISIBILITY_PRIVATE);
- if (*retp == DEBUG_FIELD_NULL)
- return false;
-
- return true;
-}
-
-/* Parse a single field in a struct or union. */
-
-static boolean
-parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- const char *p;
- debug_field *retp;
- boolean *staticsp;
-{
- const char *orig;
- char *name;
- enum debug_visibility visibility;
- debug_type type;
- bfd_vma bitpos;
- bfd_vma bitsize;
-
- orig = *pp;
-
- /* FIXME: gdb checks ARM_DEMANGLING here. */
-
- name = savestring (*pp, p - *pp);
-
- *pp = p + 1;
-
- if (**pp != '/')
- visibility = DEBUG_VISIBILITY_PUBLIC;
- else
- {
- ++*pp;
- switch (**pp)
- {
- case '0':
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
- case '1':
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- case '2':
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- default:
- warn_stab (orig, "unknown visibility character for field");
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- }
- ++*pp;
- }
-
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- if (**pp == ':')
- {
- char *varname;
-
- /* This is a static class member. */
- ++*pp;
- p = strchr (*pp, ';');
- if (p == NULL)
- {
- bad_stab (orig);
- return false;
- }
-
- varname = savestring (*pp, p - *pp);
-
- *pp = p + 1;
-
- *retp = debug_make_static_member (dhandle, name, type, varname,
- visibility);
- *staticsp = true;
-
- return true;
- }
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- bitpos = parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- bitsize = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- if (bitpos == 0 && bitsize == 0)
- {
- /* This can happen in two cases: (1) at least for gcc 2.4.5 or
- so, it is a field which has been optimized out. The correct
- stab for this case is to use VISIBILITY_IGNORE, but that is a
- recent invention. (2) It is a 0-size array. For example
- union { int num; char str[0]; } foo. Printing "<no value>"
- for str in "p foo" is OK, since foo.str (and thus foo.str[3])
- will continue to work, and a 0-size array as a whole doesn't
- have any contents to print.
-
- I suspect this probably could also happen with gcc -gstabs
- (not -gstabs+) for static fields, and perhaps other C++
- extensions. Hopefully few people use -gstabs with gdb, since
- it is intended for dbx compatibility. */
- visibility = DEBUG_VISIBILITY_IGNORE;
- }
-
- /* FIXME: gdb does some stuff here to mark fields as unpacked. */
-
- *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);
-
- return true;
-}
-
-/* Read member function stabs info for C++ classes. The form of each member
- function data is:
-
- NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
-
- An example with two member functions is:
-
- afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
-
- For the case of overloaded operators, the format is op$::*.funcs, where
- $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
- name (such as `+=') and `.' marks the end of the operator name. */
-
-static boolean
-parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char *tagname;
- const char **pp;
- const int *typenums;
- debug_method **retp;
-{
- const char *orig;
- debug_method *methods;
- unsigned int c;
- unsigned int alloc;
-
- *retp = NULL;
-
- orig = *pp;
-
- alloc = 0;
- methods = NULL;
- c = 0;
-
- while (**pp != ';')
- {
- const char *p;
- char *name;
- debug_method_variant *variants;
- unsigned int cvars;
- unsigned int allocvars;
- debug_type look_ahead_type;
-
- p = strchr (*pp, ':');
- if (p == NULL || p[1] != ':')
- break;
-
- /* FIXME: Some systems use something other than '$' here. */
- if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$')
- {
- name = savestring (*pp, p - *pp);
- *pp = p + 2;
- }
- else
- {
- /* This is a completely wierd case. In order to stuff in the
- names that might contain colons (the usual name delimiter),
- Mike Tiemann defined a different name format which is
- signalled if the identifier is "op$". In that case, the
- format is "op$::XXXX." where XXXX is the name. This is
- used for names like "+" or "=". YUUUUUUUK! FIXME! */
- *pp = p + 2;
- for (p = *pp; *p != '.' && *p != '\0'; p++)
- ;
- if (*p != '.')
- {
- bad_stab (orig);
- return false;
- }
- name = savestring (*pp, p - *pp);
- *pp = p + 1;
- }
-
- allocvars = 10;
- variants = ((debug_method_variant *)
- xmalloc (allocvars * sizeof *variants));
- cvars = 0;
-
- look_ahead_type = DEBUG_TYPE_NULL;
-
- do
- {
- debug_type type;
- boolean stub;
- char *argtypes;
- enum debug_visibility visibility;
- boolean constp, volatilep, staticp;
- bfd_vma voffset;
- debug_type context;
- const char *physname;
- boolean varargs;
-
- if (look_ahead_type != DEBUG_TYPE_NULL)
- {
- /* g++ version 1 kludge */
- type = look_ahead_type;
- look_ahead_type = DEBUG_TYPE_NULL;
- }
- else
- {
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (type == DEBUG_TYPE_NULL)
- return false;
- if (**pp != ':')
- {
- bad_stab (orig);
- return false;
- }
- }
-
- ++*pp;
- p = strchr (*pp, ';');
- if (p == NULL)
- {
- bad_stab (orig);
- return false;
- }
-
- stub = false;
- if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
- && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
- stub = true;
-
- argtypes = savestring (*pp, p - *pp);
- *pp = p + 1;
-
- switch (**pp)
- {
- case '0':
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
- case '1':
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- default:
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- }
- ++*pp;
-
- constp = false;
- volatilep = false;
- switch (**pp)
- {
- case 'A':
- /* Normal function. */
- ++*pp;
- break;
- case 'B':
- /* const member function. */
- constp = true;
- ++*pp;
- break;
- case 'C':
- /* volatile member function. */
- volatilep = true;
- ++*pp;
- break;
- case 'D':
- /* const volatile member function. */
- constp = true;
- volatilep = true;
- ++*pp;
- break;
- case '*':
- case '?':
- case '.':
- /* File compiled with g++ version 1; no information. */
- break;
- default:
- warn_stab (orig, "const/volatile indicator missing");
- break;
- }
-
- staticp = false;
- switch (**pp)
- {
- case '*':
- /* virtual member function, followed by index. The sign
- bit is supposedly set to distinguish
- pointers-to-methods from virtual function indicies. */
- ++*pp;
- voffset = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- voffset &= 0x7fffffff;
-
- if (**pp == ';' || *pp == '\0')
- {
- /* Must be g++ version 1. */
- context = DEBUG_TYPE_NULL;
- }
- else
- {
- /* Figure out from whence this virtual function
- came. It may belong to virtual function table of
- one of its baseclasses. */
- look_ahead_type = parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL);
- if (**pp == ':')
- {
- /* g++ version 1 overloaded methods. */
- context = DEBUG_TYPE_NULL;
- }
- else
- {
- context = look_ahead_type;
- look_ahead_type = DEBUG_TYPE_NULL;
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- }
- }
- break;
-
- case '?':
- /* static member function. */
- ++*pp;
- staticp = true;
- voffset = 0;
- context = DEBUG_TYPE_NULL;
- if (strncmp (argtypes, name, strlen (name)) != 0)
- stub = true;
- break;
-
- default:
- warn_stab (orig, "member function type missing");
- voffset = 0;
- context = DEBUG_TYPE_NULL;
- break;
-
- case '.':
- ++*pp;
- voffset = 0;
- context = DEBUG_TYPE_NULL;
- break;
- }
-
- /* If the type is not a stub, then the argtypes string is
- the physical name of the function. Otherwise the
- argtypes string is the mangled form of the argument
- types, and the full type and the physical name must be
- extracted from them. */
- if (! stub)
- physname = argtypes;
- else
- {
- debug_type class_type, return_type;
-
- class_type = stab_find_type (dhandle, info, typenums);
- if (class_type == DEBUG_TYPE_NULL)
- return false;
- return_type = debug_get_return_type (dhandle, type);
- if (return_type == DEBUG_TYPE_NULL)
- {
- bad_stab (orig);
- return false;
- }
- type = parse_stab_argtypes (dhandle, info, class_type, name,
- tagname, return_type, argtypes,
- constp, volatilep, &physname);
- if (type == DEBUG_TYPE_NULL)
- return false;
- }
-
- if (cvars + 1 >= allocvars)
- {
- allocvars += 10;
- variants = ((debug_method_variant *)
- xrealloc ((PTR) variants,
- allocvars * sizeof *variants));
- }
-
- if (! staticp)
- variants[cvars] = debug_make_method_variant (dhandle, physname,
- type, visibility,
- constp, volatilep,
- voffset, context);
- else
- variants[cvars] = debug_make_static_method_variant (dhandle,
- physname,
- type,
- visibility,
- constp,
- volatilep);
- if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
- return false;
-
- ++cvars;
- }
- while (**pp != ';' && **pp != '\0');
-
- variants[cvars] = DEBUG_METHOD_VARIANT_NULL;
-
- if (**pp != '\0')
- ++*pp;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- methods = ((debug_method *)
- xrealloc ((PTR) methods, alloc * sizeof *methods));
- }
-
- methods[c] = debug_make_method (dhandle, name, variants);
-
- ++c;
- }
-
- if (methods != NULL)
- methods[c] = DEBUG_METHOD_NULL;
-
- *retp = methods;
-
- return true;
-}
-
-/* Parse a string representing argument types for a method. Stabs
- tries to save space by packing argument types into a mangled
- string. This string should give us enough information to extract
- both argument types and the physical name of the function, given
- the tag name. */
-
-static debug_type
-parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
- return_type, argtypes, constp, volatilep, pphysname)
- PTR dhandle;
- struct stab_handle *info;
- debug_type class_type;
- const char *fieldname;
- const char *tagname;
- debug_type return_type;
- const char *argtypes;
- boolean constp;
- boolean volatilep;
- const char **pphysname;
-{
- boolean is_full_physname_constructor;
- boolean is_constructor;
- boolean is_destructor;
- debug_type *args;
- boolean varargs;
-
- /* Constructors are sometimes handled specially. */
- is_full_physname_constructor = ((argtypes[0] == '_'
- && argtypes[1] == '_'
- && (isdigit ((unsigned char) argtypes[2])
- || argtypes[2] == 'Q'
- || argtypes[2] == 't'))
- || strncmp (argtypes, "__ct", 4) == 0);
-
- is_constructor = (is_full_physname_constructor
- || (tagname != NULL
- && strcmp (fieldname, tagname) == 0));
- is_destructor = ((argtypes[0] == '_'
- && (argtypes[1] == '$' || argtypes[1] == '.')
- && argtypes[2] == '_')
- || strncmp (argtypes, "__dt", 4) == 0);
-
- if (is_destructor || is_full_physname_constructor)
- *pphysname = argtypes;
- else
- {
- unsigned int len;
- const char *const_prefix;
- const char *volatile_prefix;
- char buf[20];
- unsigned int mangled_name_len;
- char *physname;
-
- len = tagname == NULL ? 0 : strlen (tagname);
- const_prefix = constp ? "C" : "";
- volatile_prefix = volatilep ? "V" : "";
-
- if (len == 0)
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
- else if (tagname != NULL && strchr (tagname, '<') != NULL)
- {
- /* Template methods are fully mangled. */
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
- tagname = NULL;
- len = 0;
- }
- else
- sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
-
- mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
- + strlen (buf)
- + len
- + strlen (argtypes)
- + 1);
-
- if (fieldname[0] == 'o'
- && fieldname[1] == 'p'
- && (fieldname[2] == '$' || fieldname[2] == '.'))
- {
- const char *opname;
-
- opname = cplus_mangle_opname (fieldname + 3, 0);
- if (opname == NULL)
- {
- fprintf (stderr, "No mangling for \"%s\"\n", fieldname);
- return DEBUG_TYPE_NULL;
- }
- mangled_name_len += strlen (opname);
- physname = (char *) xmalloc (mangled_name_len);
- strncpy (physname, fieldname, 3);
- strcpy (physname + 3, opname);
- }
- else
- {
- physname = (char *) xmalloc (mangled_name_len);
- if (is_constructor)
- physname[0] = '\0';
- else
- strcpy (physname, fieldname);
- }
-
- strcat (physname, buf);
- if (tagname != NULL)
- strcat (physname, tagname);
- strcat (physname, argtypes);
-
- *pphysname = physname;
- }
-
- if (*argtypes == '\0' || is_destructor)
- {
- args = (debug_type *) xmalloc (sizeof *args);
- *args = NULL;
- return debug_make_method_type (dhandle, return_type, class_type, args,
- false);
- }
-
- args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
- if (args == NULL)
- return DEBUG_TYPE_NULL;
-
- return debug_make_method_type (dhandle, return_type, class_type, args,
- varargs);
-}
-
-/* The tail end of stabs for C++ classes that contain a virtual function
- pointer contains a tilde, a %, and a type number.
- The type number refers to the base class (possibly this class itself) which
- contains the vtable pointer for the current class.
-
- This function is called when we have parsed all the method declarations,
- so we can look for the vptr base class info. */
-
-static boolean
-parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- const int *typenums;
- debug_type *retvptrbase;
- boolean *retownvptr;
-{
- const char *orig;
- const char *hold;
- int vtypenums[2];
-
- *retvptrbase = DEBUG_TYPE_NULL;
- *retownvptr = false;
-
- orig = *pp;
-
- /* If we are positioned at a ';', then skip it. */
- if (**pp == ';')
- ++*pp;
-
- if (**pp != '~')
- return true;
-
- ++*pp;
-
- if (**pp == '=' || **pp == '+' || **pp == '-')
- {
- /* Obsolete flags that used to indicate the presence of
- constructors and/or destructors. */
- ++*pp;
- }
-
- if (**pp != '%')
- return true;
-
- ++*pp;
-
- hold = *pp;
-
- /* The next number is the type number of the base class (possibly
- our own class) which supplies the vtable for this class. */
- if (! parse_stab_type_number (pp, vtypenums))
- return false;
-
- if (vtypenums[0] == typenums[0]
- && vtypenums[1] == typenums[1])
- *retownvptr = true;
- else
- {
- debug_type vtype;
- const char *p;
-
- *pp = hold;
-
- vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- for (p = *pp; *p != ';' && *p != '\0'; p++)
- ;
- if (*p != ';')
- {
- bad_stab (orig);
- return false;
- }
-
- *retvptrbase = vtype;
-
- *pp = p + 1;
- }
-
- return true;
-}
-
-/* Read a definition of an array type. */
-
-static debug_type
-parse_stab_array_type (dhandle, info, pp, stringp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- boolean stringp;
-{
- const char *orig;
- const char *p;
- int typenums[2];
- debug_type index_type;
- boolean adjustable;
- bfd_signed_vma lower, upper;
- debug_type element_type;
-
- /* Format of an array type:
- "ar<index type>;lower;upper;<array_contents_type>".
- OS9000: "arlower,upper;<array_contents_type>".
-
- Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
- for these, produce a type like float[][]. */
-
- orig = *pp;
-
- /* FIXME: gdb checks os9k_stabs here. */
-
- /* If the index type is type 0, we take it as int. */
- p = *pp;
- if (! parse_stab_type_number (&p, typenums))
- return DEBUG_TYPE_NULL;
- if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
- {
- index_type = debug_find_named_type (dhandle, "int");
- if (index_type == DEBUG_TYPE_NULL)
- {
- index_type = debug_make_int_type (dhandle, 4, false);
- if (index_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- }
- *pp = p;
- }
- else
- {
- index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- }
-
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- adjustable = false;
-
- if (! isdigit ((unsigned char) **pp) && **pp != '-')
- {
- ++*pp;
- adjustable = true;
- }
-
- lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (! isdigit ((unsigned char) **pp) && **pp != '-')
- {
- ++*pp;
- adjustable = true;
- }
-
- upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (element_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (adjustable)
- {
- lower = 0;
- upper = -1;
- }
-
- return debug_make_array_type (dhandle, element_type, index_type, lower,
- upper, stringp);
-}
-
-/* This struct holds information about files we have seen using
- N_BINCL. */
-
-struct bincl_file
-{
- /* The next N_BINCL file. */
- struct bincl_file *next;
- /* The next N_BINCL on the stack. */
- struct bincl_file *next_stack;
- /* The file name. */
- const char *name;
- /* The hash value. */
- bfd_vma hash;
- /* The file index. */
- unsigned int file;
- /* The list of types defined in this file. */
- struct stab_types *file_types;
-};
-
-/* Start a new N_BINCL file, pushing it onto the stack. */
-
-static void
-push_bincl (info, name, hash)
- struct stab_handle *info;
- const char *name;
- bfd_vma hash;
-{
- struct bincl_file *n;
-
- n = (struct bincl_file *) xmalloc (sizeof *n);
- n->next = info->bincl_list;
- n->next_stack = info->bincl_stack;
- n->name = name;
- n->hash = hash;
- n->file = info->files;
- n->file_types = NULL;
- info->bincl_list = n;
- info->bincl_stack = n;
-
- ++info->files;
- info->file_types = ((struct stab_types **)
- xrealloc ((PTR) info->file_types,
- (info->files
- * sizeof *info->file_types)));
- info->file_types[n->file] = NULL;
-}
-
-/* Finish an N_BINCL file, at an N_EINCL, popping the name off the
- stack. */
-
-static const char *
-pop_bincl (info)
- struct stab_handle *info;
-{
- struct bincl_file *o;
-
- o = info->bincl_stack;
- if (o == NULL)
- return info->main_filename;
- info->bincl_stack = o->next_stack;
-
- o->file_types = info->file_types[o->file];
-
- if (info->bincl_stack == NULL)
- return info->main_filename;
- return info->bincl_stack->name;
-}
-
-/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */
-
-static boolean
-find_excl (info, name, hash)
- struct stab_handle *info;
- const char *name;
- bfd_vma hash;
-{
- struct bincl_file *l;
-
- ++info->files;
- info->file_types = ((struct stab_types **)
- xrealloc ((PTR) info->file_types,
- (info->files
- * sizeof *info->file_types)));
-
- for (l = info->bincl_list; l != NULL; l = l->next)
- if (l->hash == hash && strcmp (l->name, name) == 0)
- break;
- if (l == NULL)
- {
- warn_stab (name, "Undefined N_EXCL");
- info->file_types[info->files - 1] = NULL;
- return true;
- }
-
- info->file_types[info->files - 1] = l->file_types;
-
- return true;
-}
-
-/* Handle a variable definition. gcc emits variable definitions for a
- block before the N_LBRAC, so we must hold onto them until we see
- it. The SunPRO compiler emits variable definitions after the
- N_LBRAC, so we can call debug_record_variable immediately. */
-
-static boolean
-stab_record_variable (dhandle, info, name, type, kind, val)
- PTR dhandle;
- struct stab_handle *info;
- const char *name;
- debug_type type;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct stab_pending_var *v;
-
- if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
- || ! info->within_function
- || (info->gcc_compiled == 0 && info->n_opt_found))
- return debug_record_variable (dhandle, name, type, kind, val);
-
- v = (struct stab_pending_var *) xmalloc (sizeof *v);
- memset (v, 0, sizeof *v);
-
- v->next = info->pending;
- v->name = name;
- v->type = type;
- v->kind = kind;
- v->val = val;
- info->pending = v;
-
- return true;
-}
-
-/* Emit pending variable definitions. This is called after we see the
- N_LBRAC that starts the block. */
-
-static boolean
-stab_emit_pending_vars (dhandle, info)
- PTR dhandle;
- struct stab_handle *info;
-{
- struct stab_pending_var *v;
-
- v = info->pending;
- while (v != NULL)
- {
- struct stab_pending_var *next;
-
- if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
- return false;
-
- next = v->next;
- free (v);
- v = next;
- }
-
- info->pending = NULL;
-
- return true;
-}
-
-/* Find the slot for a type in the database. */
-
-static debug_type *
-stab_find_slot (info, typenums)
- struct stab_handle *info;
- const int *typenums;
-{
- int filenum;
- int index;
- struct stab_types **ps;
-
- filenum = typenums[0];
- index = typenums[1];
-
- if (filenum < 0 || (unsigned int) filenum >= info->files)
- {
- fprintf (stderr, "Type file number %d out of range\n", filenum);
- return NULL;
- }
- if (index < 0)
- {
- fprintf (stderr, "Type index number %d out of range\n", index);
- return NULL;
- }
-
- ps = info->file_types + filenum;
-
- while (index >= STAB_TYPES_SLOTS)
- {
- if (*ps == NULL)
- {
- *ps = (struct stab_types *) xmalloc (sizeof **ps);
- memset (*ps, 0, sizeof **ps);
- }
- ps = &(*ps)->next;
- index -= STAB_TYPES_SLOTS;
- }
- if (*ps == NULL)
- {
- *ps = (struct stab_types *) xmalloc (sizeof **ps);
- memset (*ps, 0, sizeof **ps);
- }
-
- return (*ps)->types + index;
-}
-
-/* Find a type given a type number. If the type has not been
- allocated yet, create an indirect type. */
-
-static debug_type
-stab_find_type (dhandle, info, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const int *typenums;
-{
- debug_type *slot;
-
- if (typenums[0] == 0 && typenums[1] < 0)
- {
- /* A negative type number indicates an XCOFF builtin type. */
- return stab_xcoff_builtin_type (dhandle, info, typenums[1]);
- }
-
- slot = stab_find_slot (info, typenums);
- if (slot == NULL)
- return DEBUG_TYPE_NULL;
-
- if (*slot == DEBUG_TYPE_NULL)
- return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
-
- return *slot;
-}
-
-/* Record that a given type number refers to a given type. */
-
-static boolean
-stab_record_type (dhandle, info, typenums, type)
- PTR dhandle;
- struct stab_handle *info;
- const int *typenums;
- debug_type type;
-{
- debug_type *slot;
-
- slot = stab_find_slot (info, typenums);
- if (slot == NULL)
- return false;
-
- /* gdb appears to ignore type redefinitions, so we do as well. */
-
- *slot = type;
-
- return true;
-}
-
-/* Return an XCOFF builtin type. */
-
-static debug_type
-stab_xcoff_builtin_type (dhandle, info, typenum)
- PTR dhandle;
- struct stab_handle *info;
- int typenum;
-{
- debug_type rettype;
- const char *name;
-
- if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
- {
- fprintf (stderr, "Unrecognized XCOFF type %d\n", typenum);
- return DEBUG_TYPE_NULL;
- }
- if (info->xcoff_types[-typenum] != NULL)
- return info->xcoff_types[-typenum];
-
- switch (-typenum)
- {
- case 1:
- /* The size of this and all the other types are fixed, defined
- by the debugging format. */
- name = "int";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 2:
- name = "char";
- rettype = debug_make_int_type (dhandle, 1, false);
- break;
- case 3:
- name = "short";
- rettype = debug_make_int_type (dhandle, 2, false);
- break;
- case 4:
- name = "long";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 5:
- name = "unsigned char";
- rettype = debug_make_int_type (dhandle, 1, true);
- break;
- case 6:
- name = "signed char";
- rettype = debug_make_int_type (dhandle, 1, false);
- break;
- case 7:
- name = "unsigned short";
- rettype = debug_make_int_type (dhandle, 2, true);
- break;
- case 8:
- name = "unsigned int";
- rettype = debug_make_int_type (dhandle, 4, true);
- break;
- case 9:
- name = "unsigned";
- rettype = debug_make_int_type (dhandle, 4, true);
- case 10:
- name = "unsigned long";
- rettype = debug_make_int_type (dhandle, 4, true);
- break;
- case 11:
- name = "void";
- rettype = debug_make_void_type (dhandle);
- break;
- case 12:
- /* IEEE single precision (32 bit). */
- name = "float";
- rettype = debug_make_float_type (dhandle, 4);
- break;
- case 13:
- /* IEEE double precision (64 bit). */
- name = "double";
- rettype = debug_make_float_type (dhandle, 8);
- break;
- case 14:
- /* This is an IEEE double on the RS/6000, and different machines
- with different sizes for "long double" should use different
- negative type numbers. See stabs.texinfo. */
- name = "long double";
- rettype = debug_make_float_type (dhandle, 8);
- break;
- case 15:
- name = "integer";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 16:
- name = "boolean";
- rettype = debug_make_bool_type (dhandle, 4);
- break;
- case 17:
- name = "short real";
- rettype = debug_make_float_type (dhandle, 4);
- break;
- case 18:
- name = "real";
- rettype = debug_make_float_type (dhandle, 8);
- break;
- case 19:
- /* FIXME */
- name = "stringptr";
- rettype = NULL;
- break;
- case 20:
- /* FIXME */
- name = "character";
- rettype = debug_make_int_type (dhandle, 1, true);
- break;
- case 21:
- name = "logical*1";
- rettype = debug_make_bool_type (dhandle, 1);
- break;
- case 22:
- name = "logical*2";
- rettype = debug_make_bool_type (dhandle, 2);
- break;
- case 23:
- name = "logical*4";
- rettype = debug_make_bool_type (dhandle, 4);
- break;
- case 24:
- name = "logical";
- rettype = debug_make_bool_type (dhandle, 4);
- break;
- case 25:
- /* Complex type consisting of two IEEE single precision values. */
- name = "complex";
- rettype = debug_make_complex_type (dhandle, 8);
- break;
- case 26:
- /* Complex type consisting of two IEEE double precision values. */
- name = "double complex";
- rettype = debug_make_complex_type (dhandle, 16);
- break;
- case 27:
- name = "integer*1";
- rettype = debug_make_int_type (dhandle, 1, false);
- break;
- case 28:
- name = "integer*2";
- rettype = debug_make_int_type (dhandle, 2, false);
- break;
- case 29:
- name = "integer*4";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 30:
- /* FIXME */
- name = "wchar";
- rettype = debug_make_int_type (dhandle, 2, false);
- break;
- case 31:
- name = "long long";
- rettype = debug_make_int_type (dhandle, 8, false);
- break;
- case 32:
- name = "unsigned long long";
- rettype = debug_make_int_type (dhandle, 8, true);
- break;
- case 33:
- name = "logical*8";
- rettype = debug_make_bool_type (dhandle, 8);
- break;
- case 34:
- name = "integer*8";
- rettype = debug_make_int_type (dhandle, 8, false);
- break;
- default:
- abort ();
- }
-
- rettype = debug_name_type (dhandle, name, rettype);
-
- info->xcoff_types[-typenum] = rettype;
-
- return rettype;
-}
-
-/* Find or create a tagged type. */
-
-static debug_type
-stab_find_tagged_type (dhandle, info, p, len, kind)
- PTR dhandle;
- struct stab_handle *info;
- const char *p;
- int len;
- enum debug_type_kind kind;
-{
- char *name;
- debug_type dtype;
- struct stab_tag *st;
-
- name = savestring (p, len);
-
- /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same
- namespace. This is right for C, and I don't know how to handle
- other languages. FIXME. */
- dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL);
- if (dtype != DEBUG_TYPE_NULL)
- {
- free (name);
- return dtype;
- }
-
- /* We need to allocate an entry on the undefined tag list. */
- for (st = info->tags; st != NULL; st = st->next)
- {
- if (st->name[0] == name[0]
- && strcmp (st->name, name) == 0)
- {
- if (st->kind == DEBUG_KIND_ILLEGAL)
- st->kind = kind;
- free (name);
- break;
- }
- }
- if (st == NULL)
- {
- st = (struct stab_tag *) xmalloc (sizeof *st);
- memset (st, 0, sizeof *st);
-
- st->next = info->tags;
- st->name = name;
- st->kind = kind;
- st->slot = DEBUG_TYPE_NULL;
- st->type = debug_make_indirect_type (dhandle, &st->slot, name);
- info->tags = st;
- }
-
- return st->type;
-}
-
-/* In order to get the correct argument types for a stubbed method, we
- need to extract the argument types from a C++ mangled string.
- Since the argument types can refer back to the return type, this
- means that we must demangle the entire physical name. In gdb this
- is done by calling cplus_demangle and running the results back
- through the C++ expression parser. Since we have no expression
- parser, we must duplicate much of the work of cplus_demangle here.
-
- We assume that GNU style demangling is used, since this is only
- done for method stubs, and only g++ should output that form of
- debugging information. */
-
-/* This structure is used to hold a pointer to type information which
- demangling a string. */
-
-struct stab_demangle_typestring
-{
- /* The start of the type. This is not null terminated. */
- const char *typestring;
- /* The length of the type. */
- unsigned int len;
-};
-
-/* This structure is used to hold information while demangling a
- string. */
-
-struct stab_demangle_info
-{
- /* The debugging information handle. */
- PTR dhandle;
- /* The stab information handle. */
- struct stab_handle *info;
- /* The array of arguments we are building. */
- debug_type *args;
- /* Whether the method takes a variable number of arguments. */
- boolean varargs;
- /* The array of types we have remembered. */
- struct stab_demangle_typestring *typestrings;
- /* The number of typestrings. */
- unsigned int typestring_count;
- /* The number of typestring slots we have allocated. */
- unsigned int typestring_alloc;
-};
-
-static void stab_bad_demangle PARAMS ((const char *));
-static unsigned int stab_demangle_count PARAMS ((const char **));
-static boolean stab_demangle_get_count
- PARAMS ((const char **, unsigned int *));
-static boolean stab_demangle_prefix
- PARAMS ((struct stab_demangle_info *, const char **));
-static boolean stab_demangle_function_name
- PARAMS ((struct stab_demangle_info *, const char **, const char *));
-static boolean stab_demangle_signature
- PARAMS ((struct stab_demangle_info *, const char **));
-static boolean stab_demangle_qualified
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
-static boolean stab_demangle_template
- PARAMS ((struct stab_demangle_info *, const char **));
-static boolean stab_demangle_class
- PARAMS ((struct stab_demangle_info *, const char **, const char **));
-static boolean stab_demangle_args
- PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
- boolean *));
-static boolean stab_demangle_arg
- PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
- unsigned int *, unsigned int *));
-static boolean stab_demangle_type
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
-static boolean stab_demangle_fund_type
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
-static boolean stab_demangle_remember_type
- PARAMS ((struct stab_demangle_info *, const char *, int));
-
-/* Warn about a bad demangling. */
-
-static void
-stab_bad_demangle (s)
- const char *s;
-{
- fprintf (stderr, "bad mangled name `%s'\n", s);
-}
-
-/* Get a count from a stab string. */
-
-static unsigned int
-stab_demangle_count (pp)
- const char **pp;
-{
- unsigned int count;
-
- count = 0;
- while (isdigit ((unsigned char) **pp))
- {
- count *= 10;
- count += **pp - '0';
- ++*pp;
- }
- return count;
-}
-
-/* Require a count in a string. The count may be multiple digits, in
- which case it must end in an underscore. */
-
-static boolean
-stab_demangle_get_count (pp, pi)
- const char **pp;
- unsigned int *pi;
-{
- if (! isdigit ((unsigned char) **pp))
- return false;
-
- *pi = **pp - '0';
- ++*pp;
- if (isdigit ((unsigned char) **pp))
- {
- unsigned int count;
- const char *p;
-
- count = *pi;
- p = *pp;
- do
- {
- count *= 10;
- count += *p - '0';
- ++p;
- }
- while (isdigit ((unsigned char) *p));
- if (*p == '_')
- {
- *pp = p + 1;
- *pi = count;
- }
- }
-
- return true;
-}
-
-/* This function demangles a physical name, returning a NULL
- terminated array of argument types. */
-
-static debug_type *
-stab_demangle_argtypes (dhandle, info, physname, pvarargs)
- PTR dhandle;
- struct stab_handle *info;
- const char *physname;
- boolean *pvarargs;
-{
- struct stab_demangle_info minfo;
-
- minfo.dhandle = dhandle;
- minfo.info = info;
- minfo.args = NULL;
- minfo.varargs = false;
- minfo.typestring_alloc = 10;
- minfo.typestrings = ((struct stab_demangle_typestring *)
- xmalloc (minfo.typestring_alloc
- * sizeof *minfo.typestrings));
- minfo.typestring_count = 0;
-
- /* cplus_demangle checks for special GNU mangled forms, but we can't
- see any of them in mangled method argument types. */
-
- if (! stab_demangle_prefix (&minfo, &physname))
- goto error_return;
-
- if (*physname != '\0')
- {
- if (! stab_demangle_signature (&minfo, &physname))
- goto error_return;
- }
-
- free (minfo.typestrings);
- minfo.typestrings = NULL;
-
- if (minfo.args == NULL)
- fprintf (stderr, "no argument types in mangled string\n");
-
- *pvarargs = minfo.varargs;
- return minfo.args;
-
- error_return:
- if (minfo.typestrings != NULL)
- free (minfo.typestrings);
- return NULL;
-}
-
-/* Demangle the prefix of the mangled name. */
-
-static boolean
-stab_demangle_prefix (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
-{
- const char *scan;
- unsigned int i;
-
- /* cplus_demangle checks for global constructors and destructors,
- but we can't see them in mangled argument types. */
-
- /* Look for `__'. */
- scan = *pp;
- do
- {
- scan = strchr (scan, '_');
- }
- while (scan != NULL && *++scan != '_');
-
- if (scan == NULL)
- {
- stab_bad_demangle (*pp);
- return false;
- }
-
- --scan;
-
- /* We found `__'; move ahead to the last contiguous `__' pair. */
- i = strspn (scan, "_");
- if (i > 2)
- scan += i - 2;
-
- if (scan == *pp
- && (isdigit ((unsigned char) scan[2])
- || scan[2] == 'Q'
- || scan[2] == 't'))
- {
- /* This is a GNU style constructor name. */
- *pp = scan + 2;
- return true;
- }
- else if (scan == *pp
- && ! isdigit ((unsigned char) scan[2])
- && scan[2] != 't')
- {
- /* Look for the `__' that separates the prefix from the
- signature. */
- while (*scan == '_')
- ++scan;
- scan = strstr (scan, "__");
- if (scan == NULL || scan[2] == '\0')
- {
- stab_bad_demangle (*pp);
- return false;
- }
-
- return stab_demangle_function_name (minfo, pp, scan);
- }
- else if (scan[2] != '\0')
- {
- /* The name doesn't start with `__', but it does contain `__'. */
- return stab_demangle_function_name (minfo, pp, scan);
- }
- else
- {
- stab_bad_demangle (*pp);
- return false;
- }
- /*NOTREACHED*/
-}
-
-/* Demangle a function name prefix. The scan argument points to the
- double underscore which separates the function name from the
- signature. */
-
-static boolean
-stab_demangle_function_name (minfo, pp, scan)
- struct stab_demangle_info *minfo;
- const char **pp;
- const char *scan;
-{
- const char *name;
-
- /* The string from *pp to scan is the name of the function. We
- don't care about the name, since we just looking for argument
- types. However, for conversion operators, the name may include a
- type which we must remember in order to handle backreferences. */
-
- name = *pp;
- *pp = scan + 2;
-
- if (*pp - name >= 5
- && strncmp (name, "type", 4) == 0
- && (name[4] == '$' || name[4] == '.'))
- {
- const char *tem;
-
- /* This is a type conversion operator. */
- tem = name + 5;
- if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
- return false;
- }
- else if (name[0] == '_'
- && name[1] == '_'
- && name[2] == 'o'
- && name[3] == 'p')
- {
- const char *tem;
-
- /* This is a type conversion operator. */
- tem = name + 4;
- if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
- return false;
- }
-
- return true;
-}
-
-/* Demangle the signature. This is where the argument types are
- found. */
-
-static boolean
-stab_demangle_signature (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
-{
- const char *orig;
- boolean expect_func, func_done;
- const char *hold;
-
- orig = *pp;
-
- expect_func = false;
- func_done = false;
- hold = NULL;
-
- while (**pp != '\0')
- {
- switch (**pp)
- {
- case 'Q':
- hold = *pp;
- if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
- || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
- return false;
- expect_func = true;
- hold = NULL;
- break;
-
- case 'S':
- /* Static member function. FIXME: Can this happen? */
- if (hold == NULL)
- hold = *pp;
- ++*pp;
- break;
-
- case 'C':
- /* Const member function. */
- if (hold == NULL)
- hold = *pp;
- ++*pp;
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (hold == NULL)
- hold = *pp;
- if (! stab_demangle_class (minfo, pp, (const char **) NULL)
- || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
- return false;
- expect_func = true;
- hold = NULL;
- break;
-
- case 'F':
- /* Function. I don't know if this actually happens with g++
- output. */
- hold = NULL;
- func_done = true;
- ++*pp;
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- break;
-
- case 't':
- /* Template. */
- if (hold == NULL)
- hold = *pp;
- if (! stab_demangle_template (minfo, pp)
- || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
- return false;
- hold = NULL;
- expect_func = true;
- break;
-
- case '_':
- /* At the outermost level, we cannot have a return type
- specified, so if we run into another '_' at this point we
- are dealing with a mangled name that is either bogus, or
- has been mangled by some algorithm we don't know how to
- deal with. So just reject the entire demangling. */
- stab_bad_demangle (orig);
- return false;
-
- default:
- /* Assume we have stumbled onto the first outermost function
- argument token, and start processing args. */
- func_done = true;
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- break;
- }
-
- if (expect_func)
- {
- func_done = true;
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- }
- }
-
- if (! func_done)
- {
- /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
- bar__3fooi is 'foo::bar(int)'. We get here when we find the
- first case, and need to ensure that the '(void)' gets added
- to the current declp. */
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- }
-
- return true;
-}
-
-/* Demangle a qualified name, such as "Q25Outer5Inner" which is the
- mangled form of "Outer::Inner". */
-
-static boolean
-stab_demangle_qualified (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
-{
- const char *orig;
- const char *p;
- unsigned int qualifiers;
- debug_type context;
-
- orig = *pp;
-
- switch ((*pp)[1])
- {
- case '_':
- /* GNU mangled name with more than 9 classes. The count is
- preceded by an underscore (to distinguish it from the <= 9
- case) and followed by an underscore. */
- p = *pp + 2;
- if (! isdigit ((unsigned char) *p) || *p == '0')
- {
- stab_bad_demangle (orig);
- return false;
- }
- qualifiers = atoi (p);
- while (isdigit ((unsigned char) *p))
- ++p;
- if (*p != '_')
- {
- stab_bad_demangle (orig);
- return false;
- }
- *pp = p + 1;
- break;
-
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- qualifiers = (*pp)[1] - '0';
- /* Skip an optional underscore after the count. */
- if ((*pp)[2] == '_')
- ++*pp;
- *pp += 2;
- break;
-
- case '0':
- default:
- stab_bad_demangle (orig);
- return false;
- }
-
- context = DEBUG_TYPE_NULL;
-
- /* Pick off the names. */
- while (qualifiers-- > 0)
- {
- if (**pp == '_')
- ++*pp;
- if (**pp == 't')
- {
- /* FIXME: I don't know how to handle the ptype != NULL case
- here. */
- if (! stab_demangle_template (minfo, pp))
- return false;
- }
- else
- {
- unsigned int len;
-
- len = stab_demangle_count (pp);
- if (strlen (*pp) < len)
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- if (ptype != NULL)
- {
- const debug_field *fields;
-
- fields = NULL;
- if (context != DEBUG_TYPE_NULL)
- fields = debug_get_fields (minfo->dhandle, context);
-
- context = DEBUG_TYPE_NULL;
-
- if (fields != NULL)
- {
- char *name;
-
- /* Try to find the type by looking through the
- fields of context until we find a field with the
- same type. This ought to work for a class
- defined within a class, but it won't work for,
- e.g., an enum defined within a class. stabs does
- not give us enough information to figure out the
- latter case. */
-
- name = savestring (*pp, len);
-
- for (; *fields != DEBUG_FIELD_NULL; fields++)
- {
- debug_type ft;
- const char *dn;
-
- ft = debug_get_field_type (minfo->dhandle, *fields);
- if (ft == NULL)
- return false;
- dn = debug_get_type_name (minfo->dhandle, ft);
- if (dn != NULL && strcmp (dn, name) == 0)
- {
- context = ft;
- break;
- }
- }
-
- free (name);
- }
-
- if (context == DEBUG_TYPE_NULL)
- {
- /* We have to fall back on finding the type by name.
- If there are more types to come, then this must
- be a class. Otherwise, it could be anything. */
-
- if (qualifiers == 0)
- {
- char *name;
-
- name = savestring (*pp, len);
- context = debug_find_named_type (minfo->dhandle,
- name);
- free (name);
- }
-
- if (context == DEBUG_TYPE_NULL)
- {
- context = stab_find_tagged_type (minfo->dhandle,
- minfo->info,
- *pp, len,
- (qualifiers == 0
- ? DEBUG_KIND_ILLEGAL
- : DEBUG_KIND_CLASS));
- if (context == DEBUG_TYPE_NULL)
- return false;
- }
- }
- }
-
- *pp += len;
- }
- }
-
- if (ptype != NULL)
- *ptype = context;
-
- return true;
-}
-
-/* Demangle a template. */
-
-static boolean
-stab_demangle_template (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
-{
- const char *orig;
- unsigned int r, i;
-
- orig = *pp;
-
- ++*pp;
-
- /* Skip the template name. */
- r = stab_demangle_count (pp);
- if (r == 0 || strlen (*pp) < r)
- {
- stab_bad_demangle (orig);
- return false;
- }
- *pp += r;
-
- /* Get the size of the parameter list. */
- if (stab_demangle_get_count (pp, &r) == 0)
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- for (i = 0; i < r; i++)
- {
- if (**pp == 'Z')
- {
- /* This is a type parameter. */
- ++*pp;
- if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
- return false;
- }
- else
- {
- const char *old_p;
- boolean pointerp, realp, integralp, charp, boolp;
- boolean done;
-
- old_p = *pp;
- pointerp = false;
- realp = false;
- integralp = false;
- charp = false;
- boolp = false;
- done = false;
-
- /* This is a value parameter. */
-
- if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
- return false;
-
- while (*old_p != '\0' && ! done)
- {
- switch (*old_p)
- {
- case 'P':
- case 'p':
- case 'R':
- pointerp = true;
- done = true;
- break;
- case 'C': /* Const. */
- case 'S': /* Signed. */
- case 'U': /* Unsigned. */
- case 'V': /* Volatile. */
- case 'F': /* Function. */
- case 'M': /* Member function. */
- case 'O': /* ??? */
- ++old_p;
- break;
- case 'Q': /* Qualified name. */
- integralp = true;
- done = true;
- break;
- case 'T': /* Remembered type. */
- abort ();
- case 'v': /* Void. */
- abort ();
- case 'x': /* Long long. */
- case 'l': /* Long. */
- case 'i': /* Int. */
- case 's': /* Short. */
- case 'w': /* Wchar_t. */
- integralp = true;
- done = true;
- break;
- case 'b': /* Bool. */
- boolp = true;
- done = true;
- break;
- case 'c': /* Char. */
- charp = true;
- done = true;
- break;
- case 'r': /* Long double. */
- case 'd': /* Double. */
- case 'f': /* Float. */
- realp = true;
- done = true;
- break;
- default:
- /* Assume it's a user defined integral type. */
- integralp = true;
- done = true;
- break;
- }
- }
-
- if (integralp)
- {
- if (**pp == 'm')
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- }
- else if (charp)
- {
- unsigned int val;
-
- if (**pp == 'm')
- ++*pp;
- val = stab_demangle_count (pp);
- if (val == 0)
- {
- stab_bad_demangle (orig);
- return false;
- }
- }
- else if (boolp)
- {
- unsigned int val;
-
- val = stab_demangle_count (pp);
- if (val != 0 && val != 1)
- {
- stab_bad_demangle (orig);
- return false;
- }
- }
- else if (realp)
- {
- if (**pp == 'm')
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- if (**pp == '.')
- {
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- }
- if (**pp == 'e')
- {
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- }
- }
- else if (pointerp)
- {
- unsigned int len;
-
- if (! stab_demangle_get_count (pp, &len))
- {
- stab_bad_demangle (orig);
- return false;
- }
- *pp += len;
- }
- }
- }
-
- return true;
-}
-
-/* Demangle a class name. */
-
-static boolean
-stab_demangle_class (minfo, pp, pstart)
- struct stab_demangle_info *minfo;
- const char **pp;
- const char **pstart;
-{
- const char *orig;
- unsigned int n;
-
- orig = *pp;
-
- n = stab_demangle_count (pp);
- if (strlen (*pp) < n)
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- if (pstart != NULL)
- *pstart = *pp;
-
- *pp += n;
-
- return true;
-}
-
-/* Demangle function arguments. If the pargs argument is not NULL, it
- is set to a NULL terminated array holding the arguments. */
-
-static boolean
-stab_demangle_args (minfo, pp, pargs, pvarargs)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type **pargs;
- boolean *pvarargs;
-{
- const char *orig;
- unsigned int alloc, count;
-
- orig = *pp;
-
- alloc = 10;
- if (pargs != NULL)
- {
- *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
- *pvarargs = false;
- }
- count = 0;
-
- while (**pp != '_' && **pp != '\0' && **pp != 'e')
- {
- if (**pp == 'N' || **pp == 'T')
- {
- char temptype;
- unsigned int r, t;
-
- temptype = **pp;
- ++*pp;
-
- if (temptype == 'T')
- r = 1;
- else
- {
- if (! stab_demangle_get_count (pp, &r))
- {
- stab_bad_demangle (orig);
- return false;
- }
- }
-
- if (! stab_demangle_get_count (pp, &t))
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- if (t >= minfo->typestring_count)
- {
- stab_bad_demangle (orig);
- return false;
- }
- while (r-- > 0)
- {
- const char *tem;
-
- tem = minfo->typestrings[t].typestring;
- if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
- return false;
- }
- }
- else
- {
- if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
- return false;
- }
- }
-
- if (pargs != NULL)
- (*pargs)[count] = DEBUG_TYPE_NULL;
-
- if (**pp == 'e')
- {
- if (pargs != NULL)
- *pvarargs = true;
- ++*pp;
- }
-
- return true;
-}
-
-/* Demangle a single argument. */
-
-static boolean
-stab_demangle_arg (minfo, pp, pargs, pcount, palloc)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type **pargs;
- unsigned int *pcount;
- unsigned int *palloc;
-{
- const char *start;
- debug_type type;
-
- start = *pp;
- if (! stab_demangle_type (minfo, pp,
- pargs == NULL ? (debug_type *) NULL : &type)
- || ! stab_demangle_remember_type (minfo, start, *pp - start))
- return false;
-
- if (pargs != NULL)
- {
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- if (*pcount + 1 >= *palloc)
- {
- *palloc += 10;
- *pargs = ((debug_type *)
- xrealloc (*pargs, *palloc * sizeof **pargs));
- }
- (*pargs)[*pcount] = type;
- ++*pcount;
- }
-
- return true;
-}
-
-/* Demangle a type. If the ptype argument is not NULL, *ptype is set
- to the newly allocated type. */
-
-static boolean
-stab_demangle_type (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
-{
- const char *orig;
-
- orig = *pp;
-
- switch (**pp)
- {
- case 'P':
- case 'p':
- /* A pointer type. */
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
- break;
-
- case 'R':
- /* A reference type. */
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
- break;
-
- case 'A':
- /* An array. */
- {
- unsigned long high;
-
- ++*pp;
- high = 0;
- while (**pp != '\0' && **pp != '_')
- {
- if (! isdigit ((unsigned char) **pp))
- {
- stab_bad_demangle (orig);
- return false;
- }
- high *= 10;
- high += **pp - '0';
- ++*pp;
- }
- if (**pp != '_')
- {
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
-
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- {
- debug_type int_type;
-
- int_type = debug_find_named_type (minfo->dhandle, "int");
- if (int_type == NULL)
- int_type = debug_make_int_type (minfo->dhandle, 4, false);
- *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
- 0, high, false);
- }
- }
- break;
-
- case 'T':
- /* A back reference to a remembered type. */
- {
- unsigned int i;
- const char *p;
-
- ++*pp;
- if (! stab_demangle_get_count (pp, &i))
- {
- stab_bad_demangle (orig);
- return false;
- }
- if (i >= minfo->typestring_count)
- {
- stab_bad_demangle (orig);
- return false;
- }
- p = minfo->typestrings[i].typestring;
- if (! stab_demangle_type (minfo, &p, ptype))
- return false;
- }
- break;
-
- case 'F':
- /* A function. */
- {
- debug_type *args;
- boolean varargs;
-
- ++*pp;
- if (! stab_demangle_args (minfo, pp,
- (ptype == NULL
- ? (debug_type **) NULL
- : &args),
- (ptype == NULL
- ? (boolean *) NULL
- : &varargs)))
- return false;
- if (**pp != '_')
- {
- /* cplus_demangle will accept a function without a return
- type, but I don't know when that will happen, or what
- to do if it does. */
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
- varargs);
-
- }
- break;
-
- case 'M':
- case 'O':
- {
- boolean memberp, constp, volatilep;
- debug_type *args;
- boolean varargs;
- unsigned int n;
- const char *name;
-
- memberp = **pp == 'M';
- constp = false;
- volatilep = false;
- args = NULL;
- varargs = false;
-
- ++*pp;
- if (! isdigit ((unsigned char) **pp))
- {
- stab_bad_demangle (orig);
- return false;
- }
- n = stab_demangle_count (pp);
- if (strlen (*pp) < n)
- {
- stab_bad_demangle (orig);
- return false;
- }
- name = *pp;
- *pp += n;
-
- if (memberp)
- {
- if (**pp == 'C')
- {
- constp = true;
- ++*pp;
- }
- else if (**pp == 'V')
- {
- volatilep = true;
- ++*pp;
- }
- if (**pp != 'F')
- {
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
- if (! stab_demangle_args (minfo, pp,
- (ptype == NULL
- ? (debug_type **) NULL
- : &args),
- (ptype == NULL
- ? (boolean *) NULL
- : &varargs)))
- return false;
- }
-
- if (**pp != '_')
- {
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
-
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
-
- if (ptype != NULL)
- {
- debug_type class_type;
-
- class_type = stab_find_tagged_type (minfo->dhandle, minfo->info,
- name, (int) n,
- DEBUG_KIND_CLASS);
- if (class_type == DEBUG_TYPE_NULL)
- return false;
-
- if (! memberp)
- *ptype = debug_make_offset_type (minfo->dhandle, class_type,
- *ptype);
- else
- {
- /* FIXME: We have no way to record constp or
- volatilep. */
- *ptype = debug_make_method_type (minfo->dhandle, *ptype,
- class_type, args, varargs);
- }
- }
- }
- break;
-
- case 'G':
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- break;
-
- case 'C':
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_const_type (minfo->dhandle, *ptype);
- break;
-
- case 'Q':
- {
- const char *hold;
-
- hold = *pp;
- if (! stab_demangle_qualified (minfo, pp, ptype))
- return false;
- }
- break;
-
- default:
- if (! stab_demangle_fund_type (minfo, pp, ptype))
- return false;
- break;
- }
-
- return true;
-}
-
-/* Demangle a fundamental type. If the ptype argument is not NULL,
- *ptype is set to the newly allocated type. */
-
-static boolean
-stab_demangle_fund_type (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
-{
- const char *orig;
- boolean constp, volatilep, unsignedp, signedp;
- boolean done;
-
- orig = *pp;
-
- constp = false;
- volatilep = false;
- unsignedp = false;
- signedp = false;
-
- done = false;
- while (! done)
- {
- switch (**pp)
- {
- case 'C':
- constp = true;
- ++*pp;
- break;
-
- case 'U':
- unsignedp = true;
- ++*pp;
- break;
-
- case 'S':
- signedp = true;
- ++*pp;
- break;
-
- case 'V':
- volatilep = true;
- ++*pp;
- break;
-
- default:
- done = true;
- break;
- }
- }
-
- switch (**pp)
- {
- case '\0':
- case '_':
- /* cplus_demangle permits this, but I don't know what it means. */
- stab_bad_demangle (orig);
- break;
-
- case 'v': /* void */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "void");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_void_type (minfo->dhandle);
- }
- ++*pp;
- break;
-
- case 'x': /* long long */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "long long unsigned int"
- : "long long int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp);
- }
- ++*pp;
- break;
-
- case 'l': /* long */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "long unsigned int"
- : "long int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
- }
- ++*pp;
- break;
-
- case 'i': /* int */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "unsigned int"
- : "int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
- }
- ++*pp;
- break;
-
- case 's': /* short */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "short unsigned int"
- : "short int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp);
- }
- ++*pp;
- break;
-
- case 'b': /* bool */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "bool");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_bool_type (minfo->dhandle, 4);
- }
- ++*pp;
- break;
-
- case 'c': /* char */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "unsigned char"
- : (signedp
- ? "signed char"
- : "char")));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp);
- }
- ++*pp;
- break;
-
- case 'w': /* wchar_t */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 2, true);
- }
- ++*pp;
- break;
-
- case 'r': /* long double */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "long double");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_float_type (minfo->dhandle, 8);
- }
- ++*pp;
- break;
-
- case 'd': /* double */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "double");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_float_type (minfo->dhandle, 8);
- }
- ++*pp;
- break;
-
- case 'f': /* float */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "float");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_float_type (minfo->dhandle, 4);
- }
- ++*pp;
- break;
-
- case 'G':
- ++*pp;
- if (! isdigit ((unsigned char) **pp))
- {
- stab_bad_demangle (orig);
- return false;
- }
- /* Fall through. */
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- const char *hold;
-
- if (! stab_demangle_class (minfo, pp, &hold))
- return false;
- if (ptype != NULL)
- {
- char *name;
-
- name = savestring (hold, *pp - hold);
- *ptype = debug_find_named_type (minfo->dhandle, name);
- if (*ptype == DEBUG_TYPE_NULL)
- {
- /* FIXME: It is probably incorrect to assume that
- undefined types are tagged types. */
- *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
- hold, *pp - hold,
- DEBUG_KIND_ILLEGAL);
- }
- free (name);
- }
- }
- break;
-
- case 't':
- if (! stab_demangle_template (minfo, pp))
- return false;
- if (ptype != NULL)
- {
- debug_type t;
-
- /* FIXME: I really don't know how a template should be
- represented in the current type system. Perhaps the
- template should be demangled into a string, and the type
- should be represented as a named type. However, I don't
- know what the base type of the named type should be. */
- t = debug_make_void_type (minfo->dhandle);
- t = debug_make_pointer_type (minfo->dhandle, t);
- t = debug_name_type (minfo->dhandle, "TEMPLATE", t);
- *ptype = t;
- }
- break;
-
- default:
- stab_bad_demangle (orig);
- return false;
- }
-
- if (ptype != NULL)
- {
- if (constp)
- *ptype = debug_make_const_type (minfo->dhandle, *ptype);
- if (volatilep)
- *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
- }
-
- return true;
-}
-
-/* Remember a type string in a demangled string. */
-
-static boolean
-stab_demangle_remember_type (minfo, p, len)
- struct stab_demangle_info *minfo;
- const char *p;
- int len;
-{
- if (minfo->typestring_count >= minfo->typestring_alloc)
- {
- minfo->typestring_alloc += 10;
- minfo->typestrings = ((struct stab_demangle_typestring *)
- xrealloc (minfo->typestrings,
- (minfo->typestring_alloc
- * sizeof *minfo->typestrings)));
- }
-
- minfo->typestrings[minfo->typestring_count].typestring = p;
- minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
- ++minfo->typestring_count;
-
- return true;
-}
diff --git a/regex/regexec.c b/regex/regexec.c
index 338c1bfa7fe..c0d03335b41 100644
--- a/regex/regexec.c
+++ b/regex/regexec.c
@@ -117,6 +117,7 @@ size_t nmatch;
my_regmatch_t pmatch[];
int eflags;
{
+ char *pstr = (char *) str;
register struct re_guts *g = preg->re_g;
#ifdef REDEBUG
# define GOODFLAGS(f) (f)
@@ -133,7 +134,7 @@ int eflags;
if ((size_t) g->nstates <= CHAR_BIT*sizeof(states1) &&
!(eflags&REG_LARGE))
- return(smatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
+ return(smatcher(preg->charset, g, pstr, nmatch, pmatch, eflags));
else
- return(lmatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
+ return(lmatcher(preg->charset, g, pstr, nmatch, pmatch, eflags));
}
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 0b22481f850..40a3565cb91 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -41,7 +41,6 @@ mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la
LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
mysqld_LDADD = libndb.la \
@MYSQLD_EXTRA_LDFLAGS@ \
- @pstack_libs@ \
@mysql_plugin_libs@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 23a649a89fa..91c850c6009 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1718,7 +1718,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
if (action->execute)
{
- const char *old_proc_info;
+ const char *UNINIT_VAR(old_proc_info);
action->execute--;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 155d457de6b..7bcbd241541 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3050,7 +3050,9 @@ int ha_partition::write_row(uchar * buf)
my_bitmap_map *old_map;
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
THD *thd= ha_thd();
- timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
+ timestamp_auto_set_type saved_timestamp_type= table->timestamp_field_type;
+ ulong saved_sql_mode= thd->variables.sql_mode;
+ bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
#ifdef NOT_NEEDED
uchar *rec0= m_rec0;
#endif
@@ -3086,6 +3088,22 @@ int ha_partition::write_row(uchar * buf)
*/
if (error)
goto exit;
+
+ /*
+ Don't allow generation of auto_increment value the partitions handler.
+ If a partitions handler would change the value, then it might not
+ match the partition any longer.
+ This can occur if 'SET INSERT_ID = 0; INSERT (NULL)',
+ So allow this by adding 'MODE_NO_AUTO_VALUE_ON_ZERO' to sql_mode.
+ The partitions handler::next_insert_id must always be 0. Otherwise
+ we need to forward release_auto_increment, or reset it for all
+ partitions.
+ */
+ if (table->next_number_field->val_int() == 0)
+ {
+ table->auto_increment_field_not_null= TRUE;
+ thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
+ }
}
old_map= dbug_tmp_use_all_columns(table, table->read_set);
@@ -3119,7 +3137,9 @@ int ha_partition::write_row(uchar * buf)
set_auto_increment_if_higher(table->next_number_field);
reenable_binlog(thd);
exit:
- table->timestamp_field_type= orig_timestamp_type;
+ thd->variables.sql_mode= saved_sql_mode;
+ table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
+ table->timestamp_field_type= saved_timestamp_type;
DBUG_RETURN(error);
}
@@ -3186,11 +3206,24 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
}
else
{
+ Field *saved_next_number_field= table->next_number_field;
+ /*
+ Don't allow generation of auto_increment value for update.
+ table->next_number_field is never set on UPDATE.
+ But is set for INSERT ... ON DUPLICATE KEY UPDATE,
+ and since update_row() does not generate or update an auto_inc value,
+ we cannot have next_number_field set when moving a row
+ to another partition with write_row(), since that could
+ generate/update the auto_inc value.
+ This gives the same behavior for partitioned vs non partitioned tables.
+ */
+ table->next_number_field= NULL;
DBUG_PRINT("info", ("Update from partition %d to partition %d",
old_part_id, new_part_id));
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[new_part_id]->ha_write_row(new_data);
reenable_binlog(thd);
+ table->next_number_field= saved_next_number_field;
if (error)
goto exit;
diff --git a/sql/handler.cc b/sql/handler.cc
index a47a5fd8a3c..1525ca53bca 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4141,7 +4141,7 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int UNINIT_VAR(result);
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 3dbff43bb67..f8c6f48d8f5 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -157,7 +157,14 @@ Item_func::fix_fields(THD *thd, Item **ref)
used_tables_cache= not_null_tables_cache= 0;
const_item_cache=1;
- if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
+ /*
+ Use stack limit of STACK_MIN_SIZE * 2 since
+ on some platforms a recursive call to fix_fields
+ requires more than STACK_MIN_SIZE bytes (e.g. for
+ MIPS, it takes about 22kB to make one recursive
+ call to Item_func::fix_fields())
+ */
+ if (check_stack_overrun(thd, STACK_MIN_SIZE * 2, buff))
return TRUE; // Fatal error if flag is set!
if (arg_count)
{ // Print purify happy
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index ef86406e1be..47bb9509582 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -331,6 +331,7 @@ public:
const char *func_name() const { return "time_to_sec"; }
void fix_length_and_dec()
{
+ maybe_null= TRUE;
decimals=0;
max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d9c4c7fc3f5..d17ccc47abb 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -70,10 +70,8 @@
#endif
/* stack traces are only supported on linux intel */
-#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK)
+#if defined(__linux__) && defined(__i386__)
#define HAVE_STACK_TRACE_ON_SEGV
-#include "../pstack/pstack.h"
-char pstack_file_name[80];
#endif /* __linux__ */
/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
@@ -2779,14 +2777,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
if (!opt_bootstrap)
create_pid_file();
-#ifdef HAVE_STACK_TRACE_ON_SEGV
- if (opt_do_pstack)
- {
- sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
- pstack_install_segv_action(pstack_file_name);
- }
-#endif /* HAVE_STACK_TRACE_ON_SEGV */
-
/*
signal to start_signal_handler that we are ready
This works by waiting for start_signal_handler to free mutex,
@@ -5963,9 +5953,10 @@ struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
#ifdef HAVE_STACK_TRACE_ON_SEGV
- {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
- &opt_do_pstack, &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
- 0, 0, 0, 0},
+ {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. "
+ "This option is deprecated and has no effect; a symbolic stack trace will "
+ "be printed after a crash whenever possible.", &opt_do_pstack, &opt_do_pstack,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_STACK_TRACE_ON_SEGV */
{"engine-condition-pushdown",
OPT_ENGINE_CONDITION_PUSHDOWN,
@@ -8654,6 +8645,13 @@ mysqld_get_one_option(int optid,
lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1;
break;
+#ifdef HAVE_STACK_TRACE_ON_SEGV
+ case OPT_DO_PSTACK:
+ sql_print_warning("'--enable-pstack' is deprecated and will be removed "
+ "in a future release. A symbolic stack trace will be "
+ "printed after a crash whenever possible.");
+ break;
+#endif
#if defined(ENABLED_DEBUG_SYNC)
case OPT_DEBUG_SYNC_TIMEOUT:
/*
diff --git a/sql/slave.cc b/sql/slave.cc
index 57d673ea1f4..644aade517c 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2321,7 +2321,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
if (slave_trans_retries)
{
- int temp_err;
+ int UNINIT_VAR(temp_err);
if (exec_res && (temp_err= has_temporary_error(thd)))
{
const char *errmsg;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 66d5eff5112..2473abea3c7 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1372,7 +1372,7 @@ sp_head::execute(THD *thd)
If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed
*/
- if (cur_db_changed && !thd->killed)
+ if (cur_db_changed && thd->killed != THD::KILL_CONNECTION)
{
/*
Force switching back to the saved current database, because it may be
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index d6f05bf5407..48d50c3a303 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6766,8 +6766,8 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
{
DBUG_ASSERT(!is_subpart);
Field *field= part_info->part_field_array[0];
- uint32 max_endpoint_val;
- get_endpoint_func get_endpoint;
+ uint32 UNINIT_VAR(max_endpoint_val);
+ get_endpoint_func UNINIT_VAR(get_endpoint);
bool can_match_multiple_values; /* is not '=' */
uint field_len= field->pack_length_in_rec();
part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index e85e730db5b..df7054c94d0 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -99,7 +99,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
*/
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
ren_table->table_name);
- DBUG_RETURN(1);
+ goto err;
}
}
else
@@ -112,7 +112,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
*/
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
ren_table->table_name);
- DBUG_RETURN(1);
+ goto err;
}
else
{
@@ -130,7 +130,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
else
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[1],
rename_log_table[1]);
- DBUG_RETURN(1);
+ goto err;
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9767839b5bf..1e5cd02bd51 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -15210,6 +15210,8 @@ calc_group_buffer(JOIN *join,ORDER *group)
{
key_length+= 8;
}
+ else if (type == MYSQL_TYPE_BLOB)
+ key_length+= MAX_BLOB_WIDTH; // Can't be used as a key
else
{
/*
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e074461b452..9b344204d64 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -534,12 +534,6 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
else if (wild_compare(uname, wild, 0))
continue;
}
- if (!(file_name=
- thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
- {
- my_dirend(dirp);
- DBUG_RETURN(FIND_FILES_OOM);
- }
}
else
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 971e1022d63..b919ea9eae7 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6832,7 +6832,6 @@ view_err:
table->alias);
}
- VOID(pthread_mutex_lock(&LOCK_open));
/*
Unlike to the above case close_cached_table() below will remove ALL
instances of TABLE from table cache (it will also remove table lock
@@ -6853,6 +6852,7 @@ view_err:
*/
ha_autocommit_or_rollback(thd, 0);
+ VOID(pthread_mutex_lock(&LOCK_open));
/*
Then do a 'simple' rename of the table. First we need to close all
instances of 'source' table.
@@ -6885,6 +6885,8 @@ view_err:
}
}
}
+ else
+ VOID(pthread_mutex_lock(&LOCK_open));
if (error == HA_ERR_WRONG_COMMAND)
{
diff --git a/storage/ibmdb2i/CMakeLists.txt b/storage/ibmdb2i/CMakeLists.txt
deleted file mode 100644
index 11cc4300569..00000000000
--- a/storage/ibmdb2i/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2006 MySQL AB
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
- ${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/extra/yassl/include)
-ADD_LIBRARY(ibmdb2i ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc
- db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc
- db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc
- db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc db2i_myconv.cc)
diff --git a/storage/ibmdb2i/Makefile.am b/storage/ibmdb2i/Makefile.am
deleted file mode 100644
index b9602e392e0..00000000000
--- a/storage/ibmdb2i/Makefile.am
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2007, 2008, IBM Corporation.
-# All rights reserved.
-#
-#
-
-#called from the top level Makefile
-
-MYSQLDATAdir = $(localstatedir)
-MYSQLSHAREdir = $(pkgdatadir)
-MYSQLBASEdir= $(prefix)
-MYSQLLIBdir= $(pkglibdir)
-pkgplugindir = $(pkglibdir)/plugin
-INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
- -I$(top_srcdir)/regex \
- -I$(top_srcdir)/sql \
- -I$(srcdir) \
- -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0f.xpf/cur/cmvc/base.pgm/my.xpf/apis \
- -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/lg.xpf \
- -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/tq.xpf
-WRAPLIBS=
-
-LDADD =
-
-DEFS = @DEFS@
-
-noinst_HEADERS = ha_ibmdb2i.h db2i_collationSupport.h db2i_file.h \
- db2i_ioBuffers.h db2i_blobCollection.h \
- db2i_global.h db2i_misc.h db2i_charsetSupport.h db2i_errors.h \
- db2i_iconv.h db2i_myconv.h db2i_safeString.h db2i_sqlStatementStream.h \
- db2i_ileBridge.h db2i_validatedPointer.h
-
-EXTRA_LTLIBRARIES = ha_ibmdb2i.la
-pkgplugin_LTLIBRARIES = @plugin_ibmdb2i_shared_target@
-ha_ibmdb2i_la_LIBADD = -liconv
-ha_ibmdb2i_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
-ha_ibmdb2i_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_ibmdb2i_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \
- db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc \
- db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc \
- db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc \
- db2i_myconv.cc
-
-EXTRA_LIBRARIES = libibmdb2i.a
-noinst_LIBRARIES = @plugin_ibmdb2i_static_target@
-libibmdb2i_a_CXXFLAGS = $(AM_CXXFLAGS)
-libibmdb2i_a_CFLAGS = $(AM_CFLAGS)
-libibmdb2i_a_SOURCES= $(ha_ibmdb2i_la_SOURCES)
-
-
-EXTRA_DIST = CMakeLists.txt plug.in
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/storage/ibmdb2i/db2i_blobCollection.cc b/storage/ibmdb2i/db2i_blobCollection.cc
deleted file mode 100644
index 17101c9c0a4..00000000000
--- a/storage/ibmdb2i/db2i_blobCollection.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_blobCollection.h"
-
-/**
- Return the size to use when allocating space for blob reads.
-
- @param fieldIndex The field to allocate for
- @param[out] shouldProtect Indicates whether storage protection should be
- applied to the space, because the size returned is
- smaller than the maximum possible size.
-*/
-
-uint32
-BlobCollection::getSizeToAllocate(int fieldIndex, bool& shouldProtect)
-{
- Field* field = table->getMySQLTable()->field[fieldIndex];
- uint fieldLength = field->max_display_length();
-
- if (fieldLength <= MAX_FULL_ALLOCATE_BLOB_LENGTH)
- {
- shouldProtect = false;
- return fieldLength;
- }
-
- shouldProtect = true;
-
- uint curMaxSize = table->getBlobFieldActualSize(fieldIndex);
-
- uint defaultAllocSize = min(defaultAllocation, fieldLength);
-
- return max(defaultAllocSize, curMaxSize);
-
-}
-
-void
-BlobCollection::generateBuffer(int fieldIndex)
-{
- DBUG_ASSERT(table->db2Field(fieldIndex).isBlob());
-
- bool protect;
- buffers[table->getBlobIdFromField(fieldIndex)].Malloc(getSizeToAllocate(fieldIndex, protect), protect);
-
- return;
-}
-
-/**
- Realloc the read buffer associated with a blob field.
-
- This is used when the previous allocation for a blob field is found to be
- too small (this is discovered when QMY_READ trips over the protected boundary
- page).
-
- @param fieldIndex The field to be reallocated
- @param size The size of buffer to allocate for this field.
-*/
-
-ValidatedPointer<char>&
-BlobCollection::reallocBuffer(int fieldIndex, size_t size)
-{
- ProtectedBuffer& buf = buffers[table->getBlobIdFromField(fieldIndex)];
- if (size <= buf.allocLen())
- return buf.ptr();
-
- table->updateBlobFieldActualSize(fieldIndex, size);
-
- DBUG_PRINT("BlobCollection::reallocBuffer",("PERF: reallocing %d to %d: ", fieldIndex, size));
-
- bool protect;
- buf.Free();
- buf.Malloc(getSizeToAllocate(fieldIndex, protect), protect);
- return buf.ptr();
-}
diff --git a/storage/ibmdb2i/db2i_blobCollection.h b/storage/ibmdb2i/db2i_blobCollection.h
deleted file mode 100644
index 6a60394555f..00000000000
--- a/storage/ibmdb2i/db2i_blobCollection.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_BLOBCOLLECTION_H
-#define DB2I_BLOBCOLLECTION_H
-
-#include "db2i_global.h"
-#include "db2i_file.h"
-
-/**
- @class ProtectedBuffer
- @brief Implements memory management for (optionally) protected buffers.
-
- Buffers created with the protection option will have a guard page set on the
- page following requested allocation size. The side effect is that the actual
- allocation is up to 2*4096-1 bytes larger than the size requested by the
- using code.
-*/
-
-class ProtectedBuffer
-{
-public:
- ProtectedBuffer() : protectBuf(false)
- {;}
-
- void Malloc(size_t size, bool protect = false)
- {
- protectBuf = protect;
- bufptr.alloc(size + (protectBuf ? 0x1fff : 0x0));
- if ((void*)bufptr != NULL)
- {
- len = size;
- if (protectBuf)
- mprotect(protectedPage(), 0x1000, PROT_NONE);
-#ifndef DBUG_OFF
- // Prevents a problem with DBUG_PRINT over-reading in recent versions of
- // MySQL
- *((char*)protectedPage()-1) = 0;
-#endif
- }
- }
-
- void Free()
- {
- if ((void*)bufptr != NULL)
- {
- if (protectBuf)
- mprotect(protectedPage(), 0x1000, PROT_READ | PROT_WRITE);
- bufptr.dealloc();
- }
- }
-
- ~ProtectedBuffer()
- {
- Free();
- }
-
- ValidatedPointer<char>& ptr() {return bufptr;}
- bool isProtected() const {return protectBuf;}
- size_t allocLen() const {return len;}
-private:
- void* protectedPage()
- {
- return (void*)(((address64_t)(void*)bufptr + len + 0x1000) & ~0xfff);
- }
-
- ValidatedPointer<char> bufptr;
- size_t len;
- bool protectBuf;
-
-};
-
-
-/**
- @class BlobCollection
- @brief Manages memory allocation for reading blobs associated with a table.
-
- Allocations are done on-demand and are protected with a guard page if less
- than the max possible size is allocated.
-*/
-class BlobCollection
-{
- public:
- BlobCollection(db2i_table* db2Table, uint32 defaultAllocSize) :
- defaultAllocation(defaultAllocSize), table(db2Table)
- {
- buffers = new ProtectedBuffer[table->getBlobCount()];
- }
-
- ~BlobCollection()
- {
- delete[] buffers;
- }
-
- ValidatedPointer<char>& getBufferPtr(int fieldIndex)
- {
- int blobIndex = table->getBlobIdFromField(fieldIndex);
- if ((char*)buffers[blobIndex].ptr() == NULL)
- generateBuffer(fieldIndex);
-
- return buffers[blobIndex].ptr();
- }
-
- ValidatedPointer<char>& reallocBuffer(int fieldIndex, size_t size);
-
-
- private:
-
- uint32 getSizeToAllocate(int fieldIndex, bool& shouldProtect);
- void generateBuffer(int fieldIndex);
-
- db2i_table* table; // The table being read
- ProtectedBuffer* buffers; // The buffers
- uint32 defaultAllocation;
- /* The default size to use when first allocating a buffer */
-};
-
-#endif
diff --git a/storage/ibmdb2i/db2i_charsetSupport.cc b/storage/ibmdb2i/db2i_charsetSupport.cc
deleted file mode 100644
index 83bf1b9448b..00000000000
--- a/storage/ibmdb2i/db2i_charsetSupport.cc
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_charsetSupport.h"
-#include "as400_types.h"
-#include "as400_protos.h"
-#include "db2i_ileBridge.h"
-#include "qlgusr.h"
-#include "db2i_errors.h"
-
-
-/*
- The following arrays define a mapping between IANA-style text descriptors and
- IBM i CCSID text descriptors. The mapping is a 1-to-1 correlation between
- corresponding array slots.
-*/
-#define MAX_IANASTRING 23
-static const char ianaStringType[MAX_IANASTRING][10] =
-{
- {"ascii"},
- {"Big5"}, //big5
- {"cp1250"},
- {"cp1251"},
- {"cp1256"},
- {"cp850"},
- {"cp852"},
- {"cp866"},
- {"IBM943"}, //cp932
- {"EUC-KR"}, //euckr
- {"IBM1381"}, //gb2312
- {"IBM1386"}, //gbk
- {"greek"},
- {"hebrew"},
- {"latin1"},
- {"latin2"},
- {"latin5"},
- {"macce"},
- {"tis620"},
- {"Shift_JIS"}, //sjis
- {"ucs2"},
- {"EUC-JP"}, //ujis
- {"utf8"}
-};
-static const char ccsidType[MAX_IANASTRING][6] =
-{
- {"367"}, //ascii
- {"950"}, //big5
- {"1250"}, //cp1250
- {"1251"}, //cp1251
- {"1256"}, //cp1256
- {"850"}, //cp850
- {"852"}, //cp852
- {"866"}, //cp866
- {"943"}, //cp932
- {"970"}, //euckr
- {"1381"}, //gb2312
- {"1386"}, //gbk
- {"813"}, //greek
- {"916"}, //hebrew
- {"923"}, //latin1
- {"912"}, //latin2
- {"920"}, //latin5
- {"1282"}, //macce
- {"874"}, //tis620
- {"943"}, //sjis
- {"13488"},//ucs2
- {"5050"}, //ujis
- {"1208"} //utf8
-};
-
-static _ILEpointer *QlgCvtTextDescToDesc_sym;
-
-/* We keep a cache of the mapping for text descriptions obtained via
- QlgTextDescToDesc. The following structures implement this cache. */
-static HASH textDescMapHash;
-static MEM_ROOT textDescMapMemroot;
-static pthread_mutex_t textDescMapHashMutex;
-struct TextDescMap
-{
- struct HashKey
- {
- int32 inType;
- int32 outType;
- char inDesc[Qlg_MaxDescSize];
- } hashKey;
- char outDesc[Qlg_MaxDescSize];
-};
-
-/* We keep a cache of the mapping for open iconv descriptors. The following
- structures implement this cache. */
-static HASH iconvMapHash;
-static MEM_ROOT iconvMapMemroot;
-static pthread_mutex_t iconvMapHashMutex;
-struct IconvMap
-{
- struct HashKey
- {
- uint32 direction; // These are uint32s to avoid garbage data in the key from compiler padding
- uint32 db2CCSID;
- const CHARSET_INFO* myCharset;
- } hashKey;
- iconv_t iconvDesc;
-};
-
-
-/**
- Initialize the static structures used by this module.
-
- This must only be called once per plugin instantiation.
-
- @return 0 if successful. Failure otherwise
-*/
-int32 initCharsetSupport()
-{
- DBUG_ENTER("initCharsetSupport");
-
- int actmark = _ILELOAD("QSYS/QLGUSR", ILELOAD_LIBOBJ);
- if ( actmark == -1 )
- {
- DBUG_PRINT("initCharsetSupport", ("conversion srvpgm activation failed"));
- DBUG_RETURN(1);
- }
-
- QlgCvtTextDescToDesc_sym = (ILEpointer*)malloc_aligned(sizeof(ILEpointer));
- if (_ILESYM(QlgCvtTextDescToDesc_sym, actmark, "QlgCvtTextDescToDesc") == -1)
- {
- DBUG_PRINT("initCharsetSupport",
- ("resolve of QlgCvtTextDescToDesc failed"));
- DBUG_RETURN(errno);
- }
-
- VOID(pthread_mutex_init(&textDescMapHashMutex,MY_MUTEX_INIT_FAST));
- hash_init(&textDescMapHash, &my_charset_bin, 10, offsetof(TextDescMap, hashKey), sizeof(TextDescMap::hashKey), 0, 0, HASH_UNIQUE);
-
- VOID(pthread_mutex_init(&iconvMapHashMutex,MY_MUTEX_INIT_FAST));
- hash_init(&iconvMapHash, &my_charset_bin, 10, offsetof(IconvMap, hashKey), sizeof(IconvMap::hashKey), 0, 0, HASH_UNIQUE);
-
- init_alloc_root(&textDescMapMemroot, 2048, 0);
- init_alloc_root(&iconvMapMemroot, 256, 0);
-
- initMyconv();
-
- DBUG_RETURN(0);
-}
-
-/**
- Cleanup the static structures used by this module.
-
- This must only be called once per plugin instantiation and only if
- initCharsetSupport() was successful.
-*/
-void doneCharsetSupport()
-{
- cleanupMyconv();
-
- free_root(&textDescMapMemroot, 0);
- free_root(&iconvMapMemroot, 0);
-
- pthread_mutex_destroy(&textDescMapHashMutex);
- hash_free(&textDescMapHash);
- pthread_mutex_destroy(&iconvMapHashMutex);
- hash_free(&iconvMapHash);
- free_aligned(QlgCvtTextDescToDesc_sym);
-}
-
-
-/**
- Convert a text description from one type to another.
-
- This function is just a wrapper for the IBM i QlgTextDescToDesc function plus
- some overrides for conversions that the API does not handle correctly and
- support for caching the computed conversion.
-
- @param inType The type of descriptor pointed to by "in".
- @param outType The type of descriptor requested for "out".
- @param in The descriptor to be convereted.
- @param[out] out The equivalent descriptor
- @param hashKey The hash key to be used for caching the conversion result.
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 getNewTextDesc(const int32 inType,
- const int32 outType,
- const char* in,
- char* out,
- const TextDescMap::HashKey* hashKey)
-{
- DBUG_ENTER("db2i_charsetSupport::getNewTextDesc");
- const arg_type_t signature[] = { ARG_INT32, ARG_INT32, ARG_MEMPTR, ARG_INT32, ARG_MEMPTR, ARG_INT32, ARG_INT32, ARG_END };
- struct ArgList
- {
- ILEarglist_base base;
- int32 CRDIInType;
- int32 CRDIOutType;
- ILEpointer CRDIDesc;
- int32 CRDIDescSize;
- ILEpointer CRDODesc;
- int32 CRDODescSize;
- int32 CTDCCSID;
- } *arguments;
-
- if ((inType == Qlg_TypeIANA) && (outType == Qlg_TypeAix41))
- {
- // Override non-standard charsets
- if (unlikely(strcmp("IBM1381", in) == 0))
- {
- strcpy(out, "IBM-1381");
- DBUG_RETURN(0);
- }
- }
- else if ((inType == Qlg_TypeAS400CCSID) && (outType == Qlg_TypeAix41))
- {
- // Override non-standard charsets
- if (strcmp("1148", in) == 0)
- {
- strcpy(out, "IBM-1148");
- DBUG_RETURN(0);
- }
- else if (unlikely(strcmp("1153", in) == 0))
- {
- strcpy(out, "IBM-1153");
- DBUG_RETURN(0);
- }
- }
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->CRDIInType = inType;
- arguments->CRDIOutType = outType;
- arguments->CRDIDesc.s.addr = (address64_t) in;
- arguments->CRDIDescSize = Qlg_MaxDescSize;
- arguments->CRDODesc.s.addr = (address64_t) out;
- arguments->CRDODescSize = Qlg_MaxDescSize;
- arguments->CTDCCSID = 819;
- _ILECALL(QlgCvtTextDescToDesc_sym,
- &arguments->base,
- signature,
- RESULT_INT32);
- if (unlikely(arguments->base.result.s_int32.r_int32 < 0))
- {
- if (arguments->base.result.s_int32.r_int32 == Qlg_InDescriptorNotFound)
- {
- DBUG_RETURN(DB2I_ERR_UNSUPP_CHARSET);
- }
- else
- {
- getErrTxt(DB2I_ERR_ILECALL,"QlgCvtTextDescToDesc",arguments->base.result.s_int32.r_int32);
- DBUG_RETURN(DB2I_ERR_ILECALL);
- }
- }
-
- // Store the conversion information into a cache entry
- TextDescMap* mapping = (TextDescMap*)alloc_root(&textDescMapMemroot, sizeof(TextDescMap));
- if (unlikely(!mapping))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- memcpy(&(mapping->hashKey), hashKey, sizeof(hashKey));
- strcpy(mapping->outDesc, out);
- pthread_mutex_lock(&textDescMapHashMutex);
- my_hash_insert(&textDescMapHash, (const uchar*)mapping);
- pthread_mutex_unlock(&textDescMapHashMutex);
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Convert a text description from one type to another.
-
- This function takes a text description in one representation and converts
- it into another representation. Although the OS provides some facilities for
- doing this, the support is not complete, nor does MySQL always use standard
- identifiers. Therefore, there are a lot of hardcoded overrides required.
- There is probably some room for optimization here, but this should not be
- called frequently under most circumstances.
-
- @param inType The type of descriptor pointed to by "in".
- @param outType The type of descriptor requested for "out".
- @param in The descriptor to be convereted.
- @param[out] out The equivalent descriptor
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 convertTextDesc(const int32 inType, const int32 outType, const char* inDesc, char* outDesc)
-{
- DBUG_ENTER("db2i_charsetSupport::convertTextDesc");
- const char* inDescOverride;
-
- if (inType == Qlg_TypeIANA)
- {
- // Override non-standard charsets
- if (strcmp("big5", inDesc) == 0)
- inDescOverride = "Big5";
- else if (strcmp("cp932", inDesc) == 0)
- inDescOverride = "IBM943";
- else if (strcmp("euckr", inDesc) == 0)
- inDescOverride = "EUC-KR";
- else if (strcmp("gb2312", inDesc) == 0)
- inDescOverride = "IBM1381";
- else if (strcmp("gbk", inDesc) == 0)
- inDescOverride = "IBM1386";
- else if (strcmp("sjis", inDesc) == 0)
- inDescOverride = "Shift_JIS";
- else if (strcmp("ujis", inDesc) == 0)
- inDescOverride = "EUC-JP";
- else
- inDescOverride = inDesc;
-
- // Hardcode non-standard charsets
- if (outType == Qlg_TypeAix41)
- {
- if (strcmp("Big5", inDescOverride) == 0)
- {
- strcpy(outDesc,"big5");
- DBUG_RETURN(0);
- }
- else if (strcmp("IBM1386", inDescOverride) == 0)
- {
- strcpy(outDesc,"GBK");
- DBUG_RETURN(0);
- }
- else if (strcmp("Shift_JIS", inDescOverride) == 0 ||
- strcmp("IBM943", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-943");
- DBUG_RETURN(0);
- }
- else if (strcmp("tis620", inDescOverride) == 0)
- {
- strcpy(outDesc,"TIS-620");
- DBUG_RETURN(0);
- }
- else if (strcmp("ucs2", inDescOverride) == 0)
- {
- strcpy(outDesc,"UCS-2");
- DBUG_RETURN(0);
- }
- else if (strcmp("cp1250", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1250");
- DBUG_RETURN(0);
- }
- else if (strcmp("cp1251", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1251");
- DBUG_RETURN(0);
- }
- else if (strcmp("cp1256", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1256");
- DBUG_RETURN(0);
- }
- else if (strcmp("macce", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1282");
- DBUG_RETURN(0);
- }
- }
- else if (outType == Qlg_TypeAS400CCSID)
- {
- // See if we can fast path the convert
- for (int loopCnt = 0; loopCnt < MAX_IANASTRING; ++loopCnt)
- {
- if (strcmp((char*)ianaStringType[loopCnt],inDescOverride) == 0)
- {
- strcpy(outDesc,ccsidType[loopCnt]);
- DBUG_RETURN(0);
- }
- }
- }
- }
- else
- inDescOverride = inDesc;
-
- // We call getNewTextDesc for all other conversions and cache the result.
- TextDescMap *mapping;
- TextDescMap::HashKey hashKey;
- hashKey.inType= inType;
- hashKey.outType= outType;
- uint32 len = strlen(inDescOverride);
- memcpy(hashKey.inDesc, inDescOverride, len);
- memset(hashKey.inDesc+len, 0, sizeof(hashKey.inDesc) - len);
-
- if (!(mapping=(TextDescMap *) hash_search(&textDescMapHash,
- (const uchar*)&hashKey,
- sizeof(hashKey))))
- {
- DBUG_RETURN(getNewTextDesc(inType, outType, inDescOverride, outDesc, &hashKey));
- }
- else
- {
- strcpy(outDesc, mapping->outDesc);
- }
- DBUG_RETURN(0);
-}
-
-
-/**
- Convert an IANA character set name into a DB2 for i CCSID value.
-
- @param parmIANADesc An IANA character set name
- @param[out] db2Ccsid The equivalent CCSID value
-
- @return 0 if successful. Failure otherwise
-*/
-int32 convertIANAToDb2Ccsid(const char* parmIANADesc, uint16* db2Ccsid)
-{
- int32 rc;
- uint16 aixCcsid;
- char aixCcsidString[Qlg_MaxDescSize];
- int aixEncodingScheme;
- int db2EncodingScheme;
- rc = convertTextDesc(Qlg_TypeIANA, Qlg_TypeAS400CCSID, parmIANADesc, aixCcsidString);
- if (unlikely(rc))
- {
- if (rc == DB2I_ERR_UNSUPP_CHARSET)
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, parmIANADesc);
-
- return rc;
- }
- aixCcsid = atoi(aixCcsidString);
- rc = getEncodingScheme(aixCcsid, aixEncodingScheme);
- if (rc != 0)
- return rc;
- switch(aixEncodingScheme) { // Select on encoding scheme
- case 0x1100: // EDCDIC SBCS
- case 0x2100: // ASCII SBCS
- case 0x4100: // AIX SBCS
- case 0x4105: // MS Windows
- case 0x5100: // ISO 7 bit ASCII
- db2EncodingScheme = 0x1100;
- break;
- case 0x1200: // EDCDIC DBCS
- case 0x2200: // ASCII DBCS
- db2EncodingScheme = 0x1200;
- break;
- case 0x1301: // EDCDIC Mixed
- case 0x2300: // ASCII Mixed
- case 0x4403: // EUC (ISO 2022)
- db2EncodingScheme = 0x1301;
- break;
- case 0x7200: // UCS2
- db2EncodingScheme = 0x7200;
- break;
- case 0x7807: // UTF-8
- db2EncodingScheme = 0x7807;
- break;
- case 0x7500: // UTF-32
- db2EncodingScheme = 0x7500;
- break;
- default: // Unknown
- {
- getErrTxt(DB2I_ERR_UNKNOWN_ENCODING,aixEncodingScheme);
- return DB2I_ERR_UNKNOWN_ENCODING;
- }
- break;
- }
- if (aixEncodingScheme == db2EncodingScheme)
- {
- *db2Ccsid = aixCcsid;
- }
- else
- {
- rc = getAssociatedCCSID(aixCcsid, db2EncodingScheme, db2Ccsid); // EDCDIC SBCS
- if (rc != 0)
- return rc;
- }
-
- return 0;
-}
-
-
-/**
- Obtain the encoding scheme of a CCSID.
-
- @param inCcsid An IBM i CCSID
- @param[out] outEncodingScheme The associated encoding scheme
-
- @return 0 if successful. Failure otherwise
-*/
-int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme)
-{
- DBUG_ENTER("db2i_charsetSupport::getEncodingScheme");
-
- static bool ptrInited = FALSE;
- static char ptrSpace[sizeof(ILEpointer) + 15];
- static ILEpointer* ptrToPtr = (ILEpointer*)roundToQuadWordBdy(ptrSpace);
- int rc;
-
- if (!ptrInited)
- {
- rc = _RSLOBJ2(ptrToPtr, RSLOBJ_TS_PGM, "QTQGESP", "QSYS");
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_RESOLVE_OBJ,"QTQGESP","QSYS","*PGM",errno);
- DBUG_RETURN(DB2I_ERR_RESOLVE_OBJ);
- }
- ptrInited = TRUE;
- }
-
- DBUG_ASSERT(inCcsid != 0);
-
- int GESPCCSID = inCcsid;
- int GESPLen = 32;
- int GESPNbrVal = 0;
- int32 GESPES;
- int GESPCSCPL[32];
- int GESPFB[3];
- void* ILEArgv[7];
- ILEArgv[0] = &GESPCCSID;
- ILEArgv[1] = &GESPLen;
- ILEArgv[2] = &GESPNbrVal;
- ILEArgv[3] = &GESPES;
- ILEArgv[4] = &GESPCSCPL;
- ILEArgv[5] = &GESPFB;
- ILEArgv[6] = NULL;
-
- rc = _PGMCALL(ptrToPtr, (void**)&ILEArgv, 0);
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_PGMCALL,"QTQGESP","QSYS",rc);
- DBUG_RETURN(DB2I_ERR_PGMCALL);
- }
- if (GESPFB[0] != 0 ||
- GESPFB[1] != 0 ||
- GESPFB[2] != 0)
- {
- getErrTxt(DB2I_ERR_QTQGESP,GESPFB[0],GESPFB[1],GESPFB[2]);
- DBUG_RETURN(DB2I_ERR_QTQGESP);
- }
- outEncodingScheme = GESPES;
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Get the best fit equivalent CCSID. (Wrapper for QTQGRDC API)
-
- @param inCcsid An IBM i CCSID
- @param inEncodingScheme The encoding scheme
- @param[out] outCcsid The equivalent CCSID
-
- @return 0 if successful. Failure otherwise
-*/
-int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint16* outCcsid)
-{
- DBUG_ENTER("db2i_charsetSupport::getAssociatedCCSID");
- static bool ptrInited = FALSE;
- static char ptrSpace[sizeof(ILEpointer) + 15];
- static ILEpointer* ptrToPtr = (ILEpointer*)roundToQuadWordBdy(ptrSpace);
- int rc;
-
- // Override non-standard charsets
- if ((inCcsid == 923) && (inEncodingScheme == 0x1100))
- {
- *outCcsid = 1148;
- DBUG_RETURN(0);
- }
- else if ((inCcsid == 1250) && (inEncodingScheme == 0x1100))
- {
- *outCcsid = 1153;
- DBUG_RETURN(0);
- }
-
- if (!ptrInited)
- {
- rc = _RSLOBJ2(ptrToPtr, RSLOBJ_TS_PGM, "QTQGRDC", "QSYS");
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_RESOLVE_OBJ,"QTQGRDC","QSYS","*PGM",errno);
- DBUG_RETURN(DB2I_ERR_RESOLVE_OBJ);
- }
- ptrInited = TRUE;
- }
-
- int GRDCCCSID = inCcsid;
- int GRDCES = inEncodingScheme;
- int GRDCSel = 0;
- int GRDCAssCCSID;
- int GRDCFB[3];
- void* ILEArgv[7];
- ILEArgv[0] = &GRDCCCSID;
- ILEArgv[1] = &GRDCES;
- ILEArgv[2] = &GRDCSel;
- ILEArgv[3] = &GRDCAssCCSID;
- ILEArgv[4] = &GRDCFB;
- ILEArgv[5] = NULL;
-
- rc = _PGMCALL(ptrToPtr, (void**)&ILEArgv, 0);
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_PGMCALL,"QTQGRDC","QSYS",rc);
- DBUG_RETURN(DB2I_ERR_PGMCALL);
- }
- if (GRDCFB[0] != 0 ||
- GRDCFB[1] != 0 ||
- GRDCFB[2] != 0)
- {
- getErrTxt(DB2I_ERR_QTQGRDC,GRDCFB[0],GRDCFB[1],GRDCFB[2]);
- DBUG_RETURN(DB2I_ERR_QTQGRDC);
- }
-
- *outCcsid = GRDCAssCCSID;
-
- DBUG_RETURN(0);
-}
-
-/**
- Open an iconv conversion between a MySQL charset and the respective IBM i CCSID
-
- @param direction The direction of the conversion
- @param mysqlCSName Name of the MySQL character set
- @param db2CCSID The IBM i CCSID
- @param hashKey The key to use for inserting the opened conversion into the cache
- @param[out] newConversion The iconv descriptor
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 openNewConversion(enum_conversionDirection direction,
- const char* mysqlCSName,
- uint16 db2CCSID,
- IconvMap::HashKey* hashKey,
- iconv_t& newConversion)
-{
- DBUG_ENTER("db2i_charsetSupport::openNewConversion");
-
- char mysqlAix41Desc[Qlg_MaxDescSize];
- char db2Aix41Desc[Qlg_MaxDescSize];
- char db2CcsidString[6] = "";
- int32 rc;
-
- /*
- First we have to convert the MySQL IANA-like name and the DB2 CCSID into
- there equivalent iconv descriptions.
- */
- rc = convertTextDesc(Qlg_TypeIANA, Qlg_TypeAix41, mysqlCSName, mysqlAix41Desc);
- if (unlikely(rc))
- {
- if (rc == DB2I_ERR_UNSUPP_CHARSET)
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName);
-
- DBUG_RETURN(rc);
- }
- CHARSET_INFO *cs= &my_charset_bin;
- (uint)(cs->cset->long10_to_str)(cs,db2CcsidString,sizeof(db2CcsidString), 10, db2CCSID);
- rc = convertTextDesc(Qlg_TypeAS400CCSID, Qlg_TypeAix41, db2CcsidString, db2Aix41Desc);
- if (unlikely(rc))
- {
- if (rc == DB2I_ERR_UNSUPP_CHARSET)
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName);
-
- DBUG_RETURN(rc);
- }
-
- /* Call iconv to open the conversion. */
- if (direction == toDB2)
- {
- newConversion = iconv_open(db2Aix41Desc, mysqlAix41Desc);
- }
- else
- {
- newConversion = iconv_open(mysqlAix41Desc, db2Aix41Desc);
- }
-
- if (unlikely(newConversion == (iconv_t) -1))
- {
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName);
- DBUG_RETURN(DB2I_ERR_UNSUPP_CHARSET);
- }
-
- /* Insert the new conversion into the cache. */
- IconvMap* mapping = (IconvMap*)alloc_root(&iconvMapMemroot, sizeof(IconvMap));
- if (!mapping)
- {
- my_error(ER_OUTOFMEMORY, MYF(0), sizeof(IconvMap));
- DBUG_RETURN( HA_ERR_OUT_OF_MEM);
- }
- memcpy(&(mapping->hashKey), hashKey, sizeof(mapping->hashKey));
- mapping->iconvDesc = newConversion;
- pthread_mutex_lock(&iconvMapHashMutex);
- my_hash_insert(&iconvMapHash, (const uchar*)mapping);
- pthread_mutex_unlock(&iconvMapHashMutex);
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Open an iconv conversion between a MySQL charset and the respective IBM i CCSID
-
- @param direction The direction of the conversion
- @param cs The MySQL character set
- @param db2CCSID The IBM i CCSID
- @param[out] newConversion The iconv descriptor
-
- @return 0 if successful. Failure otherwise
-*/
-int32 getConversion(enum_conversionDirection direction, const CHARSET_INFO* cs, uint16 db2CCSID, iconv_t& conversion)
-{
- DBUG_ENTER("db2i_charsetSupport::getConversion");
-
- int32 rc;
-
- /* Build the hash key */
- IconvMap::HashKey hashKey;
- hashKey.direction= direction;
- hashKey.myCharset= cs;
- hashKey.db2CCSID= db2CCSID;
-
- /* Look for the conversion in the cache and add it if it is not there. */
- IconvMap *mapping;
- if (!(mapping= (IconvMap *) hash_search(&iconvMapHash,
- (const uchar*)&hashKey,
- sizeof(hashKey))))
- {
- DBUG_PRINT("getConversion", ("Hash miss for direction=%d, cs=%s, ccsid=%d", direction, cs->name, db2CCSID));
- rc= openNewConversion(direction, cs->csname, db2CCSID, &hashKey, conversion);
- if (rc)
- DBUG_RETURN(rc);
- }
- else
- {
- conversion= mapping->iconvDesc;
- }
-
- DBUG_RETURN(0);
-}
-
-/**
- Fast-path conversion from ASCII to EBCDIC for use in converting
- identifiers to be sent to the QMY APIs.
-
- @param input ASCII data
- @param[out] ouput EBCDIC data
- @param ilen Size of input buffer and output buffer
-*/
-int convToEbcdic(const char* input, char* output, size_t ilen)
-{
- static bool inited = FALSE;
- static iconv_t ic;
-
- if (ilen == 0)
- return 0;
-
- if (!inited)
- {
- ic = iconv_open( "IBM-037", "ISO8859-1" );
- inited = TRUE;
- }
- size_t substitutedChars;
- size_t olen = ilen;
- if (iconv( ic, (char**)&input, &ilen, &output, &olen, &substitutedChars ) == -1)
- return errno;
-
- return 0;
-}
-
-
-/**
- Fast-path conversion from EBCDIC to ASCII for use in converting
- data received from the QMY APIs.
-
- @param input EBCDIC data
- @param[out] ouput ASCII data
- @param ilen Size of input buffer and output buffer
-*/
-int convFromEbcdic(const char* input, char* output, size_t ilen)
-{
- static bool inited = FALSE;
- static iconv_t ic;
-
- if (ilen == 0)
- return 0;
-
- if (!inited)
- {
- ic = iconv_open("ISO8859-1", "IBM-037");
- inited = TRUE;
- }
-
- size_t substitutedChars;
- size_t olen = ilen;
- if (iconv( ic, (char**)&input, &ilen, &output, &olen, &substitutedChars) == -1)
- return errno;
-
- return 0;
-}
diff --git a/storage/ibmdb2i/db2i_charsetSupport.h b/storage/ibmdb2i/db2i_charsetSupport.h
deleted file mode 100644
index 77051e1e0db..00000000000
--- a/storage/ibmdb2i/db2i_charsetSupport.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_CHARSETSUPPORT_H
-#define DB2I_CHARSETSUPPORT_H
-
-#include "db2i_global.h"
-#include "mysql_priv.h"
-#include <mysql/plugin.h>
-#include "db2i_iconv.h"
-
-/**
- @enum enum_conversionDirection
-
- Conversion directions for getConversion()
-*/
-enum enum_conversionDirection
-{
- toMySQL,
- toDB2
-};
-
-int initCharsetSupport();
-void doneCharsetSupport();
-int32 convertIANAToDb2Ccsid(const char* parmIANADesc, uint16* db2Ccsid);
-int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme);
-int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint16* outCcsid);
-int convToEbcdic(const char* input, char* output, size_t ilen);
-int convFromEbcdic(const char* input, char* output, size_t ilen);
-int32 getConversion(enum_conversionDirection direction, const CHARSET_INFO* cs, uint16 db2CCSID, iconv_t& conversion);
-
-#endif
diff --git a/storage/ibmdb2i/db2i_collationSupport.cc b/storage/ibmdb2i/db2i_collationSupport.cc
deleted file mode 100644
index 65a17fd2452..00000000000
--- a/storage/ibmdb2i/db2i_collationSupport.cc
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_collationSupport.h"
-#include "db2i_errors.h"
-
-
-/*
- The following arrays define a mapping between MySQL collation names and
- corresponding IBM i sort sequences. The mapping is a 1-to-1 correlation
- between corresponding array slots but is incomplete without case-sensitivity
- markers dynamically added to the mySqlSortSequence names.
-*/
-#define MAX_COLLATION 87
-static const char* mySQLCollation[MAX_COLLATION] =
-{
- {"ascii_general"},
- {"ascii"},
- {"big5_chinese"},
- {"big5"},
- {"cp1250_croatian"},
- {"cp1250_general"},
- {"cp1250_polish"},
- {"cp1250"},
- {"cp1251_bulgarian"},
- {"cp1251_general"},
- {"cp1251"},
- {"cp1256_general"},
- {"cp1256"},
- {"cp850_general"},
- {"cp850"},
- {"cp852_general"},
- {"cp852"},
- {"cp932_japanese"},
- {"cp932"},
- {"euckr_korean"},
- {"euckr"},
- {"gb2312_chinese"},
- {"gb2312"},
- {"gbk_chinese"},
- {"gbk"},
- {"greek_general"},
- {"greek"},
- {"hebrew_general"},
- {"hebrew"},
- {"latin1_danish"},
- {"latin1_general"},
- {"latin1_german1"},
- {"latin1_spanish"},
- {"latin1_swedish"},
- {"latin1"},
- {"latin2_croatian"},
- {"latin2_general"},
- {"latin2_hungarian"},
- {"latin2"},
- {"latin5_turkish"},
- {"latin5"},
- {"macce_general"},
- {"macce"},
- {"sjis_japanese"},
- {"sjis"},
- {"tis620_thai"},
- {"tis620"},
- {"ucs2_czech"},
- {"ucs2_danish"},
- {"ucs2_esperanto"},
- {"ucs2_estonian"},
- {"ucs2_general"},
- {"ucs2_hungarian"},
- {"ucs2_icelandic"},
- {"ucs2_latvian"},
- {"ucs2_lithuanian"},
- {"ucs2_persian"},
- {"ucs2_polish"},
- {"ucs2_romanian"},
- {"ucs2_slovak"},
- {"ucs2_slovenian"},
- {"ucs2_spanish"},
- {"ucs2_swedish"},
- {"ucs2_turkish"},
- {"ucs2_unicode"},
- {"ucs2"},
- {"ujis_japanese"},
- {"ujis"},
- {"utf8_czech"},
- {"utf8_danish"},
- {"utf8_esperanto"},
- {"utf8_estonian"},
- {"utf8_general"},
- {"utf8_hungarian"},
- {"utf8_icelandic"},
- {"utf8_latvian"},
- {"utf8_lithuanian"},
- {"utf8_persian"},
- {"utf8_polish"},
- {"utf8_romanian"},
- {"utf8_slovak"},
- {"utf8_slovenian"},
- {"utf8_spanish"},
- {"utf8_swedish"},
- {"utf8_turkish"},
- {"utf8_unicode"},
- {"utf8"}
-};
-
-
-static const char* mySqlSortSequence[MAX_COLLATION] =
-{
- {"QALA101F4"},
- {"QBLA101F4"},
- {"QACHT04B0"},
- {"QBCHT04B0"},
- {"QALA20481"},
- {"QCLA20481"},
- {"QDLA20481"},
- {"QELA20481"},
- {"QACYR0401"},
- {"QBCYR0401"},
- {"QCCYR0401"},
- {"QAARA01A4"},
- {"QBARA01A4"},
- {"QCLA101F4"},
- {"QDLA101F4"},
- {"QALA20366"},
- {"QBLA20366"},
- {"QAJPN04B0"},
- {"QBJPN04B0"},
- {"QAKOR04B0"},
- {"QBKOR04B0"},
- {"QACHS04B0"},
- {"QBCHS04B0"},
- {"QCCHS04B0"},
- {"QDCHS04B0"},
- {"QAELL036B"},
- {"QBELL036B"},
- {"QAHEB01A8"},
- {"QBHEB01A8"},
- {"QALA1047C"},
- {"QBLA1047C"},
- {"QCLA1047C"},
- {"QDLA1047C"},
- {"QELA1047C"},
- {"QFLA1047C"},
- {"QCLA20366"},
- {"QELA20366"},
- {"QFLA20366"},
- {"QGLA20366"},
- {"QATRK0402"},
- {"QBTRK0402"},
- {"QHLA20366"},
- {"QILA20366"},
- {"QCJPN04B0"},
- {"QDJPN04B0"},
- {"QATHA0346"},
- {"QBTHA0346"},
- {"ACS_CZ"},
- {"ADA_DK"},
- {"AEO"},
- {"AET"},
- {"QAUCS04B0"},
- {"AHU"},
- {"AIS"},
- {"ALV"},
- {"ALT"},
- {"AFA"},
- {"APL"},
- {"ARO"},
- {"ASK"},
- {"ASL"},
- {"AES"},
- {"ASW"},
- {"ATR"},
- {"AEN"},
- {"*HEX"},
- {"QEJPN04B0"},
- {"QFJPN04B0"},
- {"ACS_CZ"},
- {"ADA_DK"},
- {"AEO"},
- {"AET"},
- {"QAUCS04B0"},
- {"AHU"},
- {"AIS"},
- {"ALV"},
- {"ALT"},
- {"AFA"},
- {"APL"},
- {"ARO"},
- {"ASK"},
- {"ASL"},
- {"AES"},
- {"ASW"},
- {"ATR"},
- {"AEN"},
- {"*HEX"}
-};
-
-
-/**
- Get the IBM i sort sequence that corresponds to the given MySQL collation.
-
- @param fieldCharSet The collated character set
- @param[out] rtnSortSequence The corresponding sort sequence
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 getAssociatedSortSequence(const CHARSET_INFO *fieldCharSet, const char** rtnSortSequence)
-{
- DBUG_ENTER("ha_ibmdb2i::getAssociatedSortSequence");
-
- if (strcmp(fieldCharSet->csname,"binary") != 0)
- {
- int collationSearchLen = strlen(fieldCharSet->name);
- if (fieldCharSet->state & MY_CS_BINSORT)
- collationSearchLen -= 4;
- else
- collationSearchLen -= 3;
-
- uint16 loopCnt = 0;
- for (loopCnt; loopCnt < MAX_COLLATION; ++loopCnt)
- {
- if ((strlen(mySQLCollation[loopCnt]) == collationSearchLen) &&
- (strncmp((char*)mySQLCollation[loopCnt], fieldCharSet->name, collationSearchLen) == 0))
- break;
- }
- if (loopCnt == MAX_COLLATION) // Did not find associated sort sequence
- {
- getErrTxt(DB2I_ERR_SRTSEQ);
- DBUG_RETURN(DB2I_ERR_SRTSEQ);
- }
- *rtnSortSequence = mySqlSortSequence[loopCnt];
- }
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Update sort sequence information for a key.
-
- This function accumulates information about a key as it is called for each
- field composing the key. The caller should invoke the function for each field
- and (with the exception of the charset parm) preserve the values for the
- parms across invocations, until a particular key has been evaluated. Once
- the last field in the key has been evaluated, the fileSortSequence and
- fileSortSequenceLibrary parms will contain the correct information for
- creating the corresponding DB2 key.
-
- @param charset The character set under consideration
- @param[in, out] fileSortSequenceType The type of the current key's sort seq
- @param[in, out] fileSortSequence The IBM i identifier for the DB2 sort sequence
- that corresponds
-
- @return 0 if successful. Failure otherwise
-*/
-int32 updateAssociatedSortSequence(const CHARSET_INFO* charset,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary)
-{
- DBUG_ENTER("ha_ibmdb2i::updateAssociatedSortSequence");
- DBUG_ASSERT(charset);
- if (strcmp(charset->csname,"binary") != 0)
- {
- char newSortSequence[11] = "";
- char newSortSequenceType = ' ';
- const char* foundSortSequence;
- int rc = getAssociatedSortSequence(charset, &foundSortSequence);
- if (rc) DBUG_RETURN (rc);
- switch(foundSortSequence[0])
- {
- case '*': // Binary
- strcat(newSortSequence,foundSortSequence);
- newSortSequenceType = 'B';
- break;
- case 'Q': // Non-ICU sort sequence
- strcat(newSortSequence,foundSortSequence);
- if ((charset->state & MY_CS_BINSORT) != 0)
- {
- strcat(newSortSequence,"U");
- }
- else if ((charset->state & MY_CS_CSSORT) != 0)
- {
- strcat(newSortSequence,"U");
- }
- else
- {
- strcat(newSortSequence,"S");
- }
- newSortSequenceType = 'N';
- break;
- default: // ICU sort sequence
- {
- if ((charset->state & MY_CS_CSSORT) == 0)
- {
- if (osVersion.v >= 6)
- strcat(newSortSequence,"I34"); // ICU 3.4
- else
- strcat(newSortSequence,"I26"); // ICU 2.6.1
- }
- strcat(newSortSequence,foundSortSequence);
- newSortSequenceType = 'I';
- }
- break;
- }
- if (*fileSortSequenceType == ' ') // If no sort sequence has been set yet
- {
- // Set associated sort sequence
- strcpy(fileSortSequence,newSortSequence);
- strcpy(fileSortSequenceLibrary,"QSYS");
- *fileSortSequenceType = newSortSequenceType;
- }
- else if (strcmp(fileSortSequence,newSortSequence) != 0)
- {
- // Only one sort sequence/collation is supported for each DB2 index.
- getErrTxt(DB2I_ERR_MIXED_COLLATIONS);
- DBUG_RETURN(DB2I_ERR_MIXED_COLLATIONS);
- }
- }
-
- DBUG_RETURN(0);
-}
diff --git a/storage/ibmdb2i/db2i_collationSupport.h b/storage/ibmdb2i/db2i_collationSupport.h
deleted file mode 100644
index b2ce09de1ea..00000000000
--- a/storage/ibmdb2i/db2i_collationSupport.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_COLLATIONSUPPORT_H
-#define DB2I_COLLATIONSUPPORT_H
-
-#include "db2i_global.h"
-#include "mysql_priv.h"
-
-int32 updateAssociatedSortSequence(const CHARSET_INFO* charset,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary);
-
-#endif
diff --git a/storage/ibmdb2i/db2i_constraints.cc b/storage/ibmdb2i/db2i_constraints.cc
deleted file mode 100644
index 1fde0dd3d14..00000000000
--- a/storage/ibmdb2i/db2i_constraints.cc
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "ha_ibmdb2i.h"
-#include "db2i_safeString.h"
-
-// This function is called when building the CREATE TABLE information for
-// foreign key constraints. It converts a constraint, table, schema, or
-// field name from EBCDIC to ASCII. If the DB2 name is quoted, it removes
-// those quotes. It then adds the appropriate quotes for a MySQL identifier.
-
-static void convNameForCreateInfo(THD *thd, SafeString& info, char* fromName, int len)
-{
- int quote;
- char cquote; // Quote character
- char convName[MAX_DB2_FILENAME_LENGTH]; // Converted name
-
- memset(convName, 0, sizeof(convName));
- convFromEbcdic(fromName, convName, len);
- quote = get_quote_char_for_identifier(thd, convName, len);
- cquote = (char) quote;
- if (quote != EOF)
- info.strcat(cquote);
- if (convName[0] == '"') // If DB2 name was quoted, remove quotes
- {
- if (strstr(convName, "\"\""))
- stripExtraQuotes(convName+1, len-1);
- info.strncat((char*)(convName+1), len-2);
- }
- else // DB2 name was not quoted
- info.strncat(convName, len);
- if (quote != EOF)
- info.strcat(cquote);
-}
-
-/**
- Evaluate the parse tree to build foreign key constraint clauses
-
- @parm lex The parse tree
- @parm appendHere The DB2 string to receive the constraint clauses
- @parm path The path to the table under consideration
- @parm fields Pointer to the table's list of field pointers
- @parm[in, out] fileSortSequenceType The sort sequence type associated with the table
- @parm[in, out] fileSortSequence The sort sequence associated with the table
- @parm[in, out] fileSortSequenceLibrary The sort sequence library associated with the table
-
- @return 0 if successful; HA_ERR_CANNOT_ADD_FOREIGN otherwise
-*/
-int ha_ibmdb2i::buildDB2ConstraintString(LEX* lex,
- String& appendHere,
- const char* path,
- Field** fields,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary)
-{
- List_iterator<Key> keyIter(lex->alter_info.key_list);
- char colName[MAX_DB2_COLNAME_LENGTH+1];
-
- Key* curKey;
-
- while (curKey = keyIter++)
- {
- if (curKey->type == Key::FOREIGN_KEY)
- {
- appendHere.append(STRING_WITH_LEN(", "));
-
- Foreign_key* fk = (Foreign_key*)curKey;
-
- char db2LibName[MAX_DB2_SCHEMANAME_LENGTH+1];
- if (fk->name)
- {
- char db2FKName[MAX_DB2_FILENAME_LENGTH+1];
- appendHere.append(STRING_WITH_LEN("CONSTRAINT "));
- if (fk->ref_table->db.str)
- {
- convertMySQLNameToDB2Name(fk->ref_table->db.str, db2LibName, sizeof(db2LibName));
- }
- else
- {
- db2i_table::getDB2LibNameFromPath(path, db2LibName);
- }
- if (lower_case_table_names == 1)
- my_casedn_str(files_charset_info, db2LibName);
- appendHere.append(db2LibName);
-
- appendHere.append('.');
-
- convertMySQLNameToDB2Name(fk->name, db2FKName, sizeof(db2FKName));
- appendHere.append(db2FKName);
- }
-
- appendHere.append(STRING_WITH_LEN(" FOREIGN KEY ("));
-
- bool firstTime = true;
-
- List_iterator<Key_part_spec> column(fk->columns);
- Key_part_spec* curColumn;
-
- while (curColumn = column++)
- {
- if (!firstTime)
- {
- appendHere.append(',');
- }
- firstTime = false;
-
- convertMySQLNameToDB2Name(curColumn->field_name, colName, sizeof(colName));
- appendHere.append(colName);
-
- // DB2 requires that the sort sequence on the child table match the parent table's
- // sort sequence. We ensure that happens by updating the sort sequence according
- // to the constrained fields.
- Field** field = fields;
- do
- {
- if (strcmp((*field)->field_name, curColumn->field_name) == 0)
- {
- int rc = updateAssociatedSortSequence((*field)->charset(),
- fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
-
- if (unlikely(rc)) return rc;
- }
- } while (*(++field));
- }
-
- firstTime = true;
-
- appendHere.append(STRING_WITH_LEN(") REFERENCES "));
-
- if (fk->ref_table->db.str)
- {
- convertMySQLNameToDB2Name(fk->ref_table->db.str, db2LibName, sizeof(db2LibName));
- }
- else
- {
- db2i_table::getDB2LibNameFromPath(path, db2LibName);
- }
- if (lower_case_table_names == 1)
- my_casedn_str(files_charset_info, db2LibName);
- appendHere.append(db2LibName);
- appendHere.append('.');
-
- char db2FileName[MAX_DB2_FILENAME_LENGTH+1];
- convertMySQLNameToDB2Name(fk->ref_table->table.str, db2FileName, sizeof(db2FileName));
- if (lower_case_table_names)
- my_casedn_str(files_charset_info, db2FileName);
- appendHere.append(db2FileName);
-
-
- if (!fk->ref_columns.is_empty())
- {
- List_iterator<Key_part_spec> ref(fk->ref_columns);
- Key_part_spec* curRef;
- appendHere.append(STRING_WITH_LEN(" ("));
-
-
- while (curRef = ref++)
- {
- if (!firstTime)
- {
- appendHere.append(',');
- }
- firstTime = false;
-
- convertMySQLNameToDB2Name(curRef->field_name, colName, sizeof(colName));
- appendHere.append(colName);
- }
-
- appendHere.append(STRING_WITH_LEN(") "));
- }
-
- if (fk->delete_opt != Foreign_key::FK_OPTION_UNDEF)
- {
- appendHere.append(STRING_WITH_LEN("ON DELETE "));
- switch (fk->delete_opt)
- {
- case Foreign_key::FK_OPTION_RESTRICT:
- appendHere.append(STRING_WITH_LEN("RESTRICT ")); break;
- case Foreign_key::FK_OPTION_CASCADE:
- appendHere.append(STRING_WITH_LEN("CASCADE ")); break;
- case Foreign_key::FK_OPTION_SET_NULL:
- appendHere.append(STRING_WITH_LEN("SET NULL ")); break;
- case Foreign_key::FK_OPTION_NO_ACTION:
- appendHere.append(STRING_WITH_LEN("NO ACTION ")); break;
- case Foreign_key::FK_OPTION_DEFAULT:
- appendHere.append(STRING_WITH_LEN("SET DEFAULT ")); break;
- default:
- return HA_ERR_CANNOT_ADD_FOREIGN; break;
- }
- }
-
- if (fk->update_opt != Foreign_key::FK_OPTION_UNDEF)
- {
- appendHere.append(STRING_WITH_LEN("ON UPDATE "));
- switch (fk->update_opt)
- {
- case Foreign_key::FK_OPTION_RESTRICT:
- appendHere.append(STRING_WITH_LEN("RESTRICT ")); break;
- case Foreign_key::FK_OPTION_NO_ACTION:
- appendHere.append(STRING_WITH_LEN("NO ACTION ")); break;
- default:
- return HA_ERR_CANNOT_ADD_FOREIGN; break;
- }
- }
-
- }
-
- }
-
- return 0;
-}
-
-
-/***********************************************************************
-Get the foreign key information in the form of a character string so
-that it can be inserted into a CREATE TABLE statement. This is used by
-the SHOW CREATE TABLE statement. The string will later be freed by the
-free_foreign_key_create_info() method.
-************************************************************************/
-
-char* ha_ibmdb2i::get_foreign_key_create_info(void)
-{
- DBUG_ENTER("ha_ibmdb2i::get_foreign_key_create_info");
- int rc = 0;
- char* infoBuffer = NULL; // Pointer to string returned to MySQL
- uint32 constraintSpaceLength;// Length of space passed to DB2
- ValidatedPointer<char> constraintSpace; // Space pointer passed to DB2
- uint32 neededLen; // Length returned from DB2
- uint32 cstCnt; // Number of foreign key constraints from DB2
- uint32 fld; //
- constraint_hdr* cstHdr; // Pointer to constraint header structure
- FK_constraint* FKCstDef; // Pointer to constraint definition structure
- cst_name* fieldName; // Pointer to field name structure
- char* tempPtr; // Temp pointer for traversing constraint space
- char convName[128];
-
- /* Allocate space to retrieve the DB2 constraint information. */
-
- if (!(share = get_share(table_share->path.str, table)))
- DBUG_RETURN(NULL);
-
- constraintSpaceLength = 5000; // Try allocating 5000 bytes and see if enough.
-
- initBridge();
-
- constraintSpace.alloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
-
- if (unlikely(rc == QMY_ERR_NEED_MORE_SPACE))
- {
- constraintSpaceLength = neededLen; // Get length of space that's needed
- constraintSpace.realloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
- }
-
- /* If constraint information was returned by DB2, build a text string */
- /* to return to MySQL. */
-
- if ((rc == 0) && (cstCnt > 0))
- {
- THD* thd = ha_thd();
- infoBuffer = (char*) my_malloc(MAX_FOREIGN_LEN + 1, MYF(MY_WME));
- if (infoBuffer == NULL)
- {
- free_share(share);
- DBUG_RETURN(NULL);
- }
-
- SafeString info(infoBuffer, MAX_FOREIGN_LEN + 1);
-
- /* Loop through the DB2 constraints and build a text string for each foreign */
- /* key constraint that is found. */
-
- tempPtr = constraintSpace;
- cstHdr = (constraint_hdr_t*)(void*)constraintSpace; // Address first constraint definition
- for (int i = 0; i < cstCnt && !info.overflowed(); ++i)
- {
- if (cstHdr->CstType[0] == QMY_CST_FK) // If this is a foreign key constraint
- {
- tempPtr = (char*)(tempPtr + cstHdr->CstDefOff);
- FKCstDef = (FK_constraint_t*)tempPtr;
-
- /* Process the constraint name. */
-
- info.strncat(STRING_WITH_LEN(",\n CONSTRAINT "));
- convNameForCreateInfo(thd, info,
- FKCstDef->CstName.Name, FKCstDef->CstName.Len);
-
- /* Process the names of the foreign keys. */
-
- info.strncat(STRING_WITH_LEN(" FOREIGN KEY ("));
- tempPtr = (char*)(tempPtr + FKCstDef->KeyColOff);
- fieldName= (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->KeyCnt; ++fld)
- {
- convNameForCreateInfo(thd, info, fieldName->Name, fieldName->Len);
- if ((fld + 1) < FKCstDef->KeyCnt)
- {
- info.strncat(STRING_WITH_LEN(", "));
- fieldName = fieldName + 1;
- }
- }
-
- /* Process the schema-name and name of the referenced table. */
-
- info.strncat(STRING_WITH_LEN(") REFERENCES "));
- convNameForCreateInfo(thd, info,
- FKCstDef->RefSchema.Name, FKCstDef->RefSchema.Len);
- info.strcat('.');
- convNameForCreateInfo(thd, info,
- FKCstDef->RefTable.Name, FKCstDef->RefTable.Len);
- info.strncat(STRING_WITH_LEN(" ("));
-
- /* Process the names of the referenced keys. */
-
- tempPtr = (char*)FKCstDef;
- tempPtr = (char*)(tempPtr + FKCstDef->RefColOff);
- fieldName= (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->RefCnt; ++fld)
- {
- convNameForCreateInfo(thd, info, fieldName->Name, fieldName->Len);
- if ((fld + 1) < FKCstDef->RefCnt)
- {
- info.strncat(STRING_WITH_LEN(", "));
- fieldName = fieldName + 1;
- }
- }
-
- /* Process the ON UPDATE and ON DELETE rules. */
-
- info.strncat(STRING_WITH_LEN(") ON UPDATE "));
- switch(FKCstDef->UpdMethod)
- {
- case QMY_NOACTION: info.strncat(STRING_WITH_LEN("NO ACTION")); break;
- case QMY_RESTRICT: info.strncat(STRING_WITH_LEN("RESTRICT")); break;
- default: break;
- }
- info.strncat(STRING_WITH_LEN(" ON DELETE "));
- switch(FKCstDef->DltMethod)
- {
- case QMY_CASCADE: info.strncat(STRING_WITH_LEN("CASCADE")); break;
- case QMY_SETDFT: info.strncat(STRING_WITH_LEN("SET DEFAULT")); break;
- case QMY_SETNULL: info.strncat(STRING_WITH_LEN("SET NULL")); break;
- case QMY_NOACTION: info.strncat(STRING_WITH_LEN("NO ACTION")); break;
- case QMY_RESTRICT: info.strncat(STRING_WITH_LEN("RESTRICT")); break;
- default: break;
- }
- }
-
- /* Address the next constraint, if any. */
-
- if ((i+1) < cstCnt)
- {
- tempPtr = (char*)cstHdr + cstHdr->CstLen;
- cstHdr = (constraint_hdr_t*)(tempPtr);
- }
- }
- }
-
- /* Cleanup and return */
- free_share(share);
-
- DBUG_RETURN(infoBuffer);
-}
-
-/***********************************************************************
-Free the foreign key create info (for a table) that was acquired by the
-get_foreign_key_create_info() method.
-***********************************************************************/
-
-void ha_ibmdb2i::free_foreign_key_create_info(char* info)
-{
- DBUG_ENTER("ha_ibmdb2i::free_foreign_key_create_info");
-
- if (info)
- {
- my_free(info, MYF(0));
- }
- DBUG_VOID_RETURN;
-}
-
-/***********************************************************************
-This method returns to MySQL a list, with one entry in the list describing
-each foreign key constraint.
-***********************************************************************/
-
-int ha_ibmdb2i::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
-{
- DBUG_ENTER("ha_ibmdb2i::get_foreign_key_list");
- int rc = 0;
- uint32 constraintSpaceLength; // Length of space passed to DB2
- ValidatedPointer<char> constraintSpace; // Space pointer passed to DB2
- uint16 rtnCode; // Return code from DB2
- uint32 neededLen; // Bytes needed to contain DB2 constraint info
- uint32 cstCnt; // Number of constraints returned by DB2
- uint32 fld;
- constraint_hdr* cstHdr; // Pointer to a cst header structure
- FK_constraint* FKCstDef; // Pointer to definition of foreign key constraint
- cst_name* fieldName; // Pointer to field name structure
- const char *method;
- ulong methodLen;
- char* tempPtr; // Temp pointer for traversing constraint space
- char convName[128];
-
- if (!(share = get_share(table_share->path.str, table)))
- DBUG_RETURN(0);
-
- // Allocate space to retrieve the DB2 constraint information.
- constraintSpaceLength = 5000; // Try allocating 5000 bytes and see if enough.
-
- constraintSpace.alloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
-
- if (unlikely(rc == QMY_ERR_NEED_MORE_SPACE))
- {
- constraintSpaceLength = neededLen; // Get length of space that's needed
- constraintSpace.realloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
- }
-
- /* If constraint information was returned by DB2, build a text string */
- /* to return to MySQL. */
- if ((rc == 0) && (cstCnt > 0))
- {
- tempPtr = constraintSpace;
- cstHdr = (constraint_hdr_t*)(void*)constraintSpace; // Address first constraint definition
- for (int i = 0; i < cstCnt; ++i)
- {
- if (cstHdr->CstType[0] == QMY_CST_FK) // If this is a foreign key constraint
- {
- FOREIGN_KEY_INFO f_key_info;
- LEX_STRING *name= 0;
- tempPtr = (char*)(tempPtr + cstHdr->CstDefOff);
- FKCstDef = (FK_constraint_t*)tempPtr;
-
- /* Process the constraint name. */
-
- convFromEbcdic(FKCstDef->CstName.Name, convName,FKCstDef->CstName.Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- f_key_info.forein_id = thd_make_lex_string(thd, 0,
- convName + 1, (uint) (FKCstDef->CstName.Len - 2), 1);
- else // Not quoted
- f_key_info.forein_id = thd_make_lex_string(thd, 0,
- convName, (uint) FKCstDef->CstName.Len, 1);
-
- /* Process the names of the foreign keys. */
-
-
- tempPtr = (char*)(tempPtr + FKCstDef->KeyColOff);
- fieldName = (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->KeyCnt; ++fld)
- {
- convFromEbcdic(fieldName->Name, convName, fieldName->Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- name = thd_make_lex_string(thd, name,
- convName + 1, (uint) (fieldName->Len - 2), 1);
- else
- name = thd_make_lex_string(thd, name, convName, (uint) fieldName->Len, 1);
- f_key_info.foreign_fields.push_back(name);
- if ((fld + 1) < FKCstDef->KeyCnt)
- fieldName = fieldName + 1;
- }
-
- /* Process the schema and name of the referenced table. */
-
- convFromEbcdic(FKCstDef->RefSchema.Name, convName, FKCstDef->RefSchema.Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- f_key_info.referenced_db = thd_make_lex_string(thd, 0,
- convName + 1, (uint) (FKCstDef->RefSchema.Len -2), 1);
- else
- f_key_info.referenced_db = thd_make_lex_string(thd, 0,
- convName, (uint) FKCstDef->RefSchema.Len, 1);
- convFromEbcdic(FKCstDef->RefTable.Name, convName, FKCstDef->RefTable.Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- f_key_info.referenced_table = thd_make_lex_string(thd, 0,
- convName +1, (uint) (FKCstDef->RefTable.Len -2), 1);
- else
- f_key_info.referenced_table = thd_make_lex_string(thd, 0,
- convName, (uint) FKCstDef->RefTable.Len, 1);
-
- /* Process the names of the referenced keys. */
-
- tempPtr = (char*)FKCstDef;
- tempPtr = (char*)(tempPtr + FKCstDef->RefColOff);
- fieldName= (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->RefCnt; ++fld)
- {
- convFromEbcdic(fieldName->Name, convName, fieldName->Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- name = thd_make_lex_string(thd, name,
- convName + 1, (uint) (fieldName->Len -2), 1);
- else
- name = thd_make_lex_string(thd, name, convName, (uint) fieldName->Len, 1);
- f_key_info.referenced_fields.push_back(name);
- if ((fld + 1) < FKCstDef->RefCnt)
- fieldName = fieldName + 1;
- }
-
- /* Process the ON UPDATE and ON DELETE rules. */
-
- switch(FKCstDef->UpdMethod)
- {
- case QMY_NOACTION:
- {
- method = "NO ACTION";
- methodLen=9;
- }
- break;
- case QMY_RESTRICT:
- {
- method = "RESTRICT";
- methodLen = 8;
- }
- break;
- default: break;
- }
- f_key_info.update_method = thd_make_lex_string(
- thd, f_key_info.update_method, method, methodLen, 1);
- switch(FKCstDef->DltMethod)
- {
- case QMY_CASCADE:
- {
- method = "CASCADE";
- methodLen = 7;
- }
- break;
- case QMY_SETDFT:
- {
- method = "SET DEFAULT";
- methodLen = 11;
- }
- break;
- case QMY_SETNULL:
- {
- method = "SET NULL";
- methodLen = 8;
- }
- break;
- case QMY_NOACTION:
- {
- method = "NO ACTION";
- methodLen = 9;
- }
- break;
- case QMY_RESTRICT:
- {
- method = "RESTRICT";
- methodLen = 8;
- }
- break;
- default: break;
- }
- f_key_info.delete_method = thd_make_lex_string(
- thd, f_key_info.delete_method, method, methodLen, 1);
- f_key_info.referenced_key_name= thd_make_lex_string(thd, 0, (char *)"", 1, 1);
- FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *)
- thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO));
- f_key_list->push_back(pf_key_info);
- }
-
- /* Address the next constraint, if any. */
-
- if ((i+1) < cstCnt)
- {
- tempPtr = (char*)cstHdr + cstHdr->CstLen;
- cstHdr = (constraint_hdr_t*)(tempPtr);
- }
- }
- }
-
- /* Cleanup and return. */
-
- free_share(share);
- DBUG_RETURN(0);
-}
-
-/***********************************************************************
-Checks if the table is referenced by a foreign key.
-Returns: 0 if not referenced (or error occurs),
- > 0 if is referenced
-***********************************************************************/
-
-uint ha_ibmdb2i::referenced_by_foreign_key(void)
-{
- DBUG_ENTER("ha_ibmdb2i::referenced_by_foreign_key");
-
- int rc = 0;
- FILE_HANDLE queryFile = 0;
- uint32 resultRowLen;
- uint32 count = 0;
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- String query(128);
- query.append(STRING_WITH_LEN(" SELECT COUNT(*) FROM SYSIBM.SQLFOREIGNKEYS WHERE PKTABLE_SCHEM = '"));
- query.append(libName+1, strlen(libName)-2); // parent library name
- query.append(STRING_WITH_LEN("' AND PKTABLE_NAME = '"));
- query.append(fileName+1, strlen(fileName)-2); // parent file name
- query.append(STRING_WITH_LEN("'"));
-
- SqlStatementStream sqlStream(query);
-
- rc = bridge()->prepOpen(sqlStream.getPtrToData(),
- &queryFile,
- &resultRowLen);
- if (rc == 0)
- {
- IOReadBuffer rowBuffer(1, resultRowLen);
- rc = bridge()->read(queryFile, rowBuffer.ptr(), QMY_READ_ONLY, QMY_NONE, QMY_FIRST);
- if (!rc) count = *((uint32*)rowBuffer.getRowN(0));
- bridge()->deallocateFile(queryFile);
- }
- DBUG_RETURN(count);
-}
diff --git a/storage/ibmdb2i/db2i_conversion.cc b/storage/ibmdb2i/db2i_conversion.cc
deleted file mode 100644
index 9a85eb01c9b..00000000000
--- a/storage/ibmdb2i/db2i_conversion.cc
+++ /dev/null
@@ -1,1459 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_ileBridge.h"
-#include "mysql_priv.h"
-#include "db2i_charsetSupport.h"
-#include "ctype.h"
-#include "ha_ibmdb2i.h"
-#include "db2i_errors.h"
-#include "wchar.h"
-
-const char ZERO_DATETIME_VALUE[] = "0000-00-00 00:00:00";
-const char ZERO_DATETIME_VALUE_SUBST[] = "0001-01-01 00:00:00";
-const char ZERO_DATE_VALUE[] = "0000-00-00";
-const char ZERO_DATE_VALUE_SUBST[] = "0001-01-01";
-
-
-/**
- Put a BCD digit into a BCD string.
-
- @param[out] bcdString The BCD string to be modified
- @param pos The position within the string to be updated.
- @param val The value to be assigned into the string at pos.
-*/
-static inline void bcdAssign(char* bcdString, uint pos, uint val)
-{
- bcdString[pos/2] |= val << ((pos % 2) ? 0 : 4);
-}
-
-/**
- Read a BCD digit from a BCD string.
-
- @param[out] bcdString The BCD string to be read
- @param pos The position within the string to be read.
-
- @return bcdGet The value of the BCD digit at pos.
-*/
-static inline uint bcdGet(const char* bcdString, uint pos)
-{
- return (bcdString[pos/2] >> ((pos % 2) ? 0 : 4)) & 0xf;
-}
-
-/**
- In-place convert a number in ASCII represenation to EBCDIC representation.
-
- @param string The string of ASCII characters
- @param len The length of string
-*/
-static inline void convertNumericToEbcdicFast(char* string, int len)
-{
- for (int i = 0; i < len; ++i, ++string)
- {
- switch(*string)
- {
- case '-':
- *string = 0x60; break;
- case ':':
- *string = 0x7A; break;
- case '.':
- *string = 0x4B; break;
- default:
- DBUG_ASSERT(isdigit(*string));
- *string += 0xF0 - '0';
- break;
- }
- }
-}
-
-
-/**
- atoi()-like function for a 4-character EBCDIC string.
-
- @param string The EBCDIC string
- @return a4toi_ebcdic The decimal value of the EBCDIC string
-*/
-static inline uint16 a4toi_ebcdic(const uchar* string)
-{
- return ((string[0]-0xF0) * 1000 +
- (string[1]-0xF0) * 100 +
- (string[2]-0xF0) * 10 +
- (string[3]-0xF0));
-};
-
-
-/**
- atoi()-like function for a 4-character EBCDIC string.
-
- @param string The EBCDIC string
- @return a4toi_ebcdic The decimal value of the EBCDIC string
-*/
-static inline uint8 a2toi_ebcdic(const uchar* string)
-{
- return ((string[0]-0xF0) * 10 +
- (string[1]-0xF0));
-};
-
-/**
- Perform character conversion for textual field data.
-*/
-int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
- uint16 fieldID,
- const char* input,
- char* output,
- size_t ilen,
- size_t olen,
- size_t* outDataLen,
- bool tacitErrors,
- size_t* substChars)
-{
- DBUG_PRINT("ha_ibmdb2i::convertFieldChars",("Direction: %d; length = %d", direction, ilen));
-
- if (unlikely(ilen == 0))
- {
- if (outDataLen) *outDataLen = 0;
- return (0);
- }
-
- iconv_t& conversion = db2Table->getConversionDefinition(direction, fieldID);
-
- if (unlikely(conversion == (iconv_t)(-1)))
- {
- return (DB2I_ERR_UNSUPP_CHARSET);
- }
-
- size_t initOLen= olen;
- size_t substitutedChars = 0;
- int rc = iconv(conversion, (char**)&input, &ilen, &output, &olen, &substitutedChars );
- if (outDataLen) *outDataLen = initOLen - olen;
- if (substChars) *substChars = substitutedChars;
- if (unlikely(rc < 0))
- {
- int er = errno;
- if (er == EILSEQ)
- {
- if (!tacitErrors) getErrTxt(DB2I_ERR_ILL_CHAR, table->field[fieldID]->field_name);
- return (DB2I_ERR_ILL_CHAR);
- }
- else
- {
- if (!tacitErrors) getErrTxt(DB2I_ERR_ICONV,er);
- return (DB2I_ERR_ICONV);
- }
- }
- if (unlikely(substitutedChars) && (!tacitErrors))
- {
- warning(ha_thd(), DB2I_ERR_SUB_CHARS, table->field[fieldID]->field_name);
- }
-
- return (0);
-}
-
-/**
- Append the appropriate default value clause onto a CREATE TABLE definition
-
- This was inspired by get_field_default_value in sql/sql_show.cc.
-
- @param field The field whose value is to be obtained
- @param statement The string to receive the DEFAULT clause
- @param quoteIt Does the data type require single quotes around the value?
- @param ccsid The ccsid of the field value (if a string type); 0 if no conversion needed
-*/
-static void get_field_default_value(Field *field,
- String &statement,
- bool quoteIt,
- uint32 ccsid,
- bool substituteZeroDates)
-{
- if ((field->type() != FIELD_TYPE_BLOB &&
- !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
- field->unireg_check != Field::NEXT_NUMBER))
- {
- my_ptrdiff_t old_ptr= (my_ptrdiff_t) (field->table->s->default_values - field->table->record[0]);
- field->move_field_offset(old_ptr);
-
- String defaultClause(64);
- defaultClause.length(0);
- defaultClause.append(" DEFAULT ");
- if (!field->is_null())
- {
- my_bitmap_map *old_map = tmp_use_all_columns(field->table, field->table->read_set);
- char tmp[MAX_FIELD_WIDTH];
-
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- CHARSET_INFO *cs= &my_charset_bin;
- uint len = (uint)(cs->cset->longlong10_to_str)(cs,tmp,sizeof(tmp), 10, field->val_int());
- tmp[len]=0;
- defaultClause.append(tmp);
- }
- else
- {
- String type(tmp, sizeof(tmp), field->charset());
- field->val_str(&type);
- if (type.length())
- {
- if (field->type() == MYSQL_TYPE_DATE &&
- memcmp(type.ptr(), STRING_WITH_LEN(ZERO_DATE_VALUE)) == 0)
- {
- if (substituteZeroDates)
- type.set(STRING_WITH_LEN(ZERO_DATE_VALUE_SUBST), field->charset());
- else
- {
- warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- return;
- }
- }
- else if ((field->type() == MYSQL_TYPE_DATETIME ||
- field->type() == MYSQL_TYPE_TIMESTAMP) &&
- memcmp(type.ptr(), STRING_WITH_LEN(ZERO_DATETIME_VALUE)) == 0)
- {
- if (substituteZeroDates)
- type.set(STRING_WITH_LEN(ZERO_DATETIME_VALUE_SUBST), field->charset());
- else
- {
- warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- return;
- }
- }
-
-
- if (field->type() != MYSQL_TYPE_STRING &&
- field->type() != MYSQL_TYPE_VARCHAR &&
- field->type() != MYSQL_TYPE_BLOB &&
- field->type() != MYSQL_TYPE_BIT)
- {
- if (quoteIt)
- defaultClause.append('\'');
- defaultClause.append(type);
- if (quoteIt)
- defaultClause.append('\'');
- }
- else
- {
- int length;
- char* out;
-
- // If a ccsid is specified, we need to make sure that the DEFAULT
- // string is converted to that encoding.
- if (ccsid != 0)
- {
- iconv_t iconvD;
- if (getConversion(toDB2, field->charset(), ccsid, iconvD))
- {
- warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- return;
- }
-
- size_t ilen = type.length();
- size_t olen = 6 * ilen;
- size_t origOlen = olen;
- const char* in = type.ptr();
- const char* tempIn = in;
- out = (char*)my_malloc(olen, MYF(MY_WME));
- char* tempOut = out;
- size_t substitutedChars;
-
- if (iconv(iconvD, (char**)&tempIn, &ilen, &tempOut, &olen, &substitutedChars) < 0)
- {
- warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- my_free(out, MYF(0));
- return;
- }
- // Now we process the converted string to represent it as
- // hexadecimal values.
-
- length = origOlen - olen;
- }
- else
- {
- length = type.length();
- out = (char*)my_malloc(length*2, MYF(MY_WME));
- memcpy(out, (char*)type.ptr(), length);
- }
-
- if (length > 16370)
- {
- warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- my_free(out, MYF(0));
- return;
- }
-
- if (ccsid == 1200)
- defaultClause.append("ux'");
- else if (ccsid == 13488)
- defaultClause.append("gx'");
- else if (field->charset() == &my_charset_bin)
- defaultClause.append("binary(x'");
- else
- defaultClause.append("x'");
-
- const char hexMap[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
- for (int c = length-1; c >= 0; --c)
- {
- out[c*2+1] = hexMap[out[c] & 0xF];
- out[c*2] = hexMap[out[c] >> 4];
- }
-
- defaultClause.append(out, length*2);
- defaultClause.append('\'');
- if (field->charset() == &my_charset_bin)
- defaultClause.append(")");
-
- my_free(out, MYF(0));
- }
- }
- else
- defaultClause.length(0);
- }
- tmp_restore_column_map(field->table->read_set, old_map);
- }
- else if (field->maybe_null())
- defaultClause.append(STRING_WITH_LEN("NULL"));
-
- if (old_ptr)
- field->move_field_offset(-old_ptr);
-
- statement.append(defaultClause);
- }
-}
-
-
-
-
-/**
- Convert a MySQL field definition into its corresponding DB2 type.
-
- The result will be appended to mapping as a DB2 SQL phrase.
-
- @param field The MySQL field to be evaluated
- @param[out] mapping The receiver for the DB2 SQL syntax
- @param timeFormat The format to be used for mapping the TIME type
-*/
-int ha_ibmdb2i::getFieldTypeMapping(Field* field,
- String& mapping,
- enum_TimeFormat timeFormat,
- enum_BlobMapping blobMapping,
- enum_ZeroDate zeroDateHandling,
- bool propagateDefaults,
- enum_YearFormat yearFormat)
-{
- char stringBuildBuffer[257];
- uint32 fieldLength;
- bool defaultNeedsQuotes = false;
- uint16 db2Ccsid = 0;
-
- CHARSET_INFO* fieldCharSet = field->charset();
- switch (field->type())
- {
- case MYSQL_TYPE_NEWDECIMAL:
- {
- uint precision= ((Field_new_decimal*)field)->precision;
- uint scale= field->decimals();
-
- if (precision <= MAX_DEC_PRECISION)
- {
- sprintf(stringBuildBuffer,"DECIMAL(%d, %d)",precision,scale);
- }
- else
- {
- if (scale > precision - MAX_DEC_PRECISION)
- {
- scale = scale - (precision - MAX_DEC_PRECISION);
- precision = MAX_DEC_PRECISION;
- sprintf(stringBuildBuffer,"DECIMAL(%d, %d)",precision,scale);
- }
- else
- {
- return HA_ERR_UNSUPPORTED;
- }
- warning(ha_thd(), DB2I_ERR_PRECISION);
- }
-
- mapping.append(stringBuildBuffer);
- }
- break;
- case MYSQL_TYPE_TINY:
- mapping.append(STRING_WITH_LEN("SMALLINT"));
- break;
- case MYSQL_TYPE_SHORT:
- if (((Field_num*)field)->unsigned_flag)
- mapping.append(STRING_WITH_LEN("INT"));
- else
- mapping.append(STRING_WITH_LEN("SMALLINT"));
- break;
- case MYSQL_TYPE_LONG:
- if (((Field_num*)field)->unsigned_flag)
- mapping.append(STRING_WITH_LEN("BIGINT"));
- else
- mapping.append(STRING_WITH_LEN("INT"));
- break;
- case MYSQL_TYPE_FLOAT:
- mapping.append(STRING_WITH_LEN("REAL"));
- break;
- case MYSQL_TYPE_DOUBLE:
- mapping.append(STRING_WITH_LEN("DOUBLE"));
- break;
- case MYSQL_TYPE_LONGLONG:
- if (((Field_num*)field)->unsigned_flag)
- mapping.append(STRING_WITH_LEN("DECIMAL(20,0)"));
- else
- mapping.append(STRING_WITH_LEN("BIGINT"));
- break;
- case MYSQL_TYPE_INT24:
- mapping.append(STRING_WITH_LEN("INTEGER"));
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- mapping.append(STRING_WITH_LEN("DATE"));
- defaultNeedsQuotes = true;
- break;
- case MYSQL_TYPE_TIME:
- if (timeFormat == TIME_OF_DAY)
- {
- mapping.append(STRING_WITH_LEN("TIME"));
- defaultNeedsQuotes = true;
- }
- else
- mapping.append(STRING_WITH_LEN("INTEGER"));
- break;
- case MYSQL_TYPE_DATETIME:
- mapping.append(STRING_WITH_LEN("TIMESTAMP"));
- defaultNeedsQuotes = true;
- break;
- case MYSQL_TYPE_TIMESTAMP:
- mapping.append(STRING_WITH_LEN("TIMESTAMP"));
-
- if (table_share->timestamp_field == field && propagateDefaults)
- {
- switch (((Field_timestamp*)field)->get_auto_set_type())
- {
- case TIMESTAMP_NO_AUTO_SET:
- break;
- case TIMESTAMP_AUTO_SET_ON_INSERT:
- mapping.append(STRING_WITH_LEN(" DEFAULT CURRENT_TIMESTAMP"));
- break;
- case TIMESTAMP_AUTO_SET_ON_UPDATE:
- if (osVersion.v >= 6 &&
- !field->is_null())
- {
- mapping.append(STRING_WITH_LEN(" GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP"));
- warning(ha_thd(), DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- }
- else
- warning(ha_thd(), DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- break;
- case TIMESTAMP_AUTO_SET_ON_BOTH:
- if (osVersion.v >= 6 &&
- !field->is_null())
- mapping.append(STRING_WITH_LEN(" GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP"));
- else
- {
- mapping.append(STRING_WITH_LEN(" DEFAULT CURRENT_TIMESTAMP"));
- warning(ha_thd(), DB2I_ERR_WARN_COL_ATTRS, field->field_name);
- }
- break;
- }
- }
- else
- defaultNeedsQuotes = true;
- break;
- case MYSQL_TYPE_YEAR:
- if (yearFormat == CHAR4)
- {
- mapping.append(STRING_WITH_LEN("CHAR(4) CCSID 1208"));
- defaultNeedsQuotes = true;
- }
- else
- {
- mapping.append(STRING_WITH_LEN("SMALLINT"));
- defaultNeedsQuotes = false;
- }
- break;
- case MYSQL_TYPE_BIT:
- sprintf(stringBuildBuffer, "BINARY(%d)", (field->max_display_length() / 8) + 1);
- mapping.append(stringBuildBuffer);
- break;
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_STRING:
- {
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- mapping.append(STRING_WITH_LEN("BIGINT"));
- }
- else
- {
- defaultNeedsQuotes = true;
-
- fieldLength = field->max_display_length(); // Get field byte length
-
- if (fieldCharSet == &my_charset_bin)
- {
- if (field->type() == MYSQL_TYPE_STRING)
- {
- sprintf(stringBuildBuffer, "BINARY(%d)", max(fieldLength, 1));
- }
- else
- {
- if (fieldLength <= MAX_VARCHAR_LENGTH)
- {
- sprintf(stringBuildBuffer, "VARBINARY(%d)", max(fieldLength, 1));
- }
- else if (blobMapping == AS_VARCHAR &&
- (field->flags & PART_KEY_FLAG))
- {
- sprintf(stringBuildBuffer, "LONG VARBINARY ");
- }
- else
- {
- fieldLength = min(MAX_BLOB_LENGTH, fieldLength);
- sprintf(stringBuildBuffer, "BLOB(%d)", max(fieldLength, 1));
- }
- }
- mapping.append(stringBuildBuffer);
- }
- else
- {
- if (field->type() == MYSQL_TYPE_STRING)
- {
- if (fieldLength > MAX_CHAR_LENGTH)
- return 1;
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1)); // Number of bytes
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1));
- }
- mapping.append(stringBuildBuffer);
- }
- else
- {
- if (fieldLength <= MAX_VARCHAR_LENGTH)
- {
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1)); // Number of bytes
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1));
- }
- }
- else if (blobMapping == AS_VARCHAR &&
- (field->flags & PART_KEY_FLAG))
- {
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "LONG VARGRAPHIC ");
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "LONG VARCHAR ");
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "LONG VARGRAPHIC ");
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "LONG VARCHAR ");
- }
- }
- else
- {
- fieldLength = min(MAX_BLOB_LENGTH, fieldLength);
-
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of bytes
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of characters
- }
- }
-
- mapping.append(stringBuildBuffer);
- }
- if (db2Ccsid == 0) // If not overriding CCSID
- {
- int32 rtnCode = convertIANAToDb2Ccsid(fieldCharSet->csname, &db2Ccsid);
- if (rtnCode)
- return rtnCode;
- }
-
- if (db2Ccsid != 1208 &&
- db2Ccsid != 13488)
- {
- // Check whether there is a character conversion available.
- iconv_t temp;
- int32 rc = getConversion(toDB2, fieldCharSet, db2Ccsid, temp);
- if (unlikely(rc))
- return rc;
- }
-
- sprintf(stringBuildBuffer, " CCSID %d ", db2Ccsid);
- mapping.append(stringBuildBuffer);
- }
- }
- }
- break;
-
- }
-
- if (propagateDefaults)
- get_field_default_value(field,
- mapping,
- defaultNeedsQuotes,
- db2Ccsid,
- (zeroDateHandling==SUBSTITUTE_0001_01_01));
-
- return 0;
-}
-
-
-/**
- Convert MySQL field data into the equivalent DB2 format
-
- @param field The MySQL field to be converted
- @param db2Field The corresponding DB2 field definition
- @param db2Buf The buffer to receive the converted data
- @param data NULL if field points to the correct data; otherwise,
- the data to be converted (for use with keys)
-*/
-int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data)
-{
- enum_field_types fieldType = field->type();
- switch (fieldType)
- {
- case MYSQL_TYPE_NEWDECIMAL:
- {
- uint precision= ((Field_new_decimal*)field)->precision;
- uint scale= field->decimals();
- uint db2Precision = min(precision, MAX_DEC_PRECISION);
- uint truncationAmount = precision - db2Precision;
-
- if (scale >= truncationAmount)
- {
- String tempString(precision+2);
-
- if (data == NULL)
- {
- field->val_str((String*)&tempString, (String*)(NULL));
- }
- else
- {
- field->val_str(&tempString, data);
- }
- const char* temp = tempString.ptr();
- char packed[32];
- memset(&packed, 0, sizeof(packed));
-
- int bcdPos = db2Precision - (db2Precision % 2 ? 1 : 0);
- bcdAssign(packed, bcdPos+1, (temp[0] == '-' ? 0xD : 0xF));
-
- int strPos=tempString.length() - 1 - truncationAmount;
-
- for (;strPos >= 0 && bcdPos >= 0; strPos--)
- {
- if (my_isdigit(&my_charset_latin1, temp[strPos]))
- {
- bcdAssign(packed, bcdPos, temp[strPos]-'0');
- --bcdPos;
- }
- }
- memcpy(db2Buf, &packed, (db2Precision/2)+1);
- }
-
- }
- break;
- case MYSQL_TYPE_TINY:
- {
- int16 temp = (data == NULL ? field->val_int() : field->val_int(data));
- memcpy(db2Buf , &temp, sizeof(temp));
- }
- break;
- case MYSQL_TYPE_SHORT:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- memset(db2Buf, 0, 2);
- memcpy(db2Buf+2, (data == NULL ? field->ptr : data), 2);
- }
- else
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 2);
- }
- }
- break;
- case MYSQL_TYPE_LONG:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- memset(db2Buf, 0, 4);
- memcpy(db2Buf+4, (data == NULL ? field->ptr : data), 4);
- }
- else
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 4);
- }
- }
- break;
- case MYSQL_TYPE_FLOAT:
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 4);
- }
- break;
- case MYSQL_TYPE_DOUBLE:
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 8);
- }
- break;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATETIME:
- {
- String tempString(27);
- if (data == NULL)
- {
- field->val_str(&tempString, &tempString);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memset(db2Buf, '0', 26);
- memcpy(db2Buf, tempString.ptr(), tempString.length());
- if (strncmp(db2Buf,ZERO_DATETIME_VALUE,strlen(ZERO_DATETIME_VALUE)) == 0)
- {
- if (cachedZeroDateOption == SUBSTITUTE_0001_01_01)
- memcpy(db2Buf, ZERO_DATETIME_VALUE_SUBST, sizeof(ZERO_DATETIME_VALUE_SUBST));
- else
- {
- getErrTxt(DB2I_ERR_INVALID_COL_VALUE, field->field_name);
- return(DB2I_ERR_INVALID_COL_VALUE);
- }
- }
- (db2Buf)[10] = '-';
- (db2Buf)[13] = (db2Buf)[16] = (db2Buf)[19] = '.';
-
- convertNumericToEbcdicFast(db2Buf, 26);
- }
- break;
- case MYSQL_TYPE_LONGLONG:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- char temp[23];
- String tempString(temp, sizeof(temp), &my_charset_latin1);
-
- if (data == NULL)
- {
- field->val_str((String*)&tempString, (String*)(NULL));
- }
- else
- {
- field->val_str(&tempString, data);
- }
- char packed[11];
- memset(packed, 0, sizeof(packed));
- bcdAssign(packed, 21, (temp[0] == '-' ? 0xD : 0xF));
- int strPos=tempString.length()-1;
- int bcdPos=20;
-
- for (;strPos >= 0; strPos--)
- {
- if (my_isdigit(&my_charset_latin1, temp[strPos]))
- {
- bcdAssign(packed, bcdPos, temp[strPos]-'0');
- --bcdPos;
- }
- }
- memcpy(db2Buf, &packed, 11);
- }
- else
- {
- *(uint64*)db2Buf = *(uint64*)(data == NULL ? field->ptr : data);
- }
- }
- break;
- case MYSQL_TYPE_INT24:
- {
- int32 temp= (data == NULL ? field->val_int() : field->val_int(data));
- memcpy(db2Buf , &temp, sizeof(temp));
- }
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- {
- String tempString(11);
- if (data == NULL)
- {
- field->val_str(&tempString, (String*)NULL);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memcpy(db2Buf, tempString.ptr(), 10);
- if (strncmp(db2Buf,ZERO_DATE_VALUE,strlen(ZERO_DATE_VALUE)) == 0)
- {
- if (cachedZeroDateOption == SUBSTITUTE_0001_01_01)
- memcpy(db2Buf, ZERO_DATE_VALUE_SUBST, sizeof(ZERO_DATE_VALUE_SUBST));
- else
- {
- getErrTxt(DB2I_ERR_INVALID_COL_VALUE,field->field_name);
- return(DB2I_ERR_INVALID_COL_VALUE);
- }
- }
-
- convertNumericToEbcdicFast(db2Buf,10);
- }
- break;
- case MYSQL_TYPE_TIME:
- {
- if (db2Field.getType() == QMY_TIME)
- {
- String tempString(10);
- if (data == NULL)
- {
- field->val_str(&tempString, (String*)NULL);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memcpy(db2Buf, tempString.ptr(), 8);
- (db2Buf)[2]=(db2Buf)[5] = '.';
-
- convertNumericToEbcdicFast(db2Buf, 8);
- }
- else
- {
- int32 temp = sint3korr(data == NULL ? field->ptr : data);
- memcpy(db2Buf, &temp, sizeof(temp));
- }
- }
- break;
- case MYSQL_TYPE_YEAR:
- {
- String tempString(5);
- if (db2Field.getType() == QMY_CHAR)
- {
- if (data == NULL)
- {
- field->val_str(&tempString, (String*)NULL);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memcpy(db2Buf, tempString.ptr(), 4);
- }
- else
- {
- uint8 temp = *(uint8*)(data == NULL ? field->ptr : data);
- *(uint16*)(db2Buf) = (temp ? temp + 1900 : 0);
- }
- }
- break;
- case MYSQL_TYPE_BIT:
- {
- int bytesToCopy = db2Field.getByteLengthInRecord();
-
- if (data == NULL)
- {
- uint64 temp = field->val_int();
- memcpy(db2Buf,
- ((char*)&temp) + (sizeof(temp) - bytesToCopy),
- bytesToCopy);
- }
- else
- {
- memcpy(db2Buf,
- data,
- bytesToCopy);
- }
- }
- break;
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_BLOB:
- {
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- int64 temp= (data == NULL ? field->val_int() : field->val_int(data));
- *(int64*)db2Buf = temp;
- }
- else
- {
- const uchar* dataToStore;
- uint32 bytesToStore;
- uint32 bytesToPad = 0;
- CHARSET_INFO* fieldCharSet = field->charset();
- uint32 maxDisplayLength = field->max_display_length();
- switch (fieldType)
- {
- case MYSQL_TYPE_STRING:
- {
- bytesToStore = maxDisplayLength;
- if (data == NULL)
- dataToStore = field->ptr;
- else
- dataToStore = data;
- }
- break;
- case MYSQL_TYPE_VARCHAR:
- {
-
- if (data == NULL)
- {
- bytesToStore = field->data_length();
- dataToStore = field->ptr + ((Field_varstring*)field)->length_bytes;
- }
- else
- {
- // Key lens are stored little-endian
- bytesToStore = *(uint8*)data + ((*(uint8*)(data+1)) << 8);
- dataToStore = data + 2;
- }
- bytesToPad = maxDisplayLength - bytesToStore;
- }
- break;
- case MYSQL_TYPE_BLOB:
- {
- if (data == NULL)
- {
- bytesToStore = ((Field_blob*)field)->get_length();
- bytesToPad = maxDisplayLength - bytesToStore;
- ((Field_blob*)field)->get_ptr((uchar**)&dataToStore);
- }
- else
- {
- // Key lens are stored little-endian
- bytesToStore = *(uint8*)data + ((*(uint8*)(data+1)) << 8);
- dataToStore = data + 2;
- }
- }
- break;
- }
-
- int32 rc;
- uint16 db2FieldType = db2Field.getType();
- switch(db2FieldType)
- {
- case QMY_CHAR:
- if (maxDisplayLength == 0)
- bytesToPad = 1;
- case QMY_VARCHAR:
- if (db2FieldType == QMY_VARCHAR)
- {
- db2Buf += sizeof(uint16);
- bytesToPad = 0;
- }
-
- if (bytesToStore > db2Field.getDataLengthInRecord())
- {
- bytesToStore = db2Field.getDataLengthInRecord();
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
- }
-
- if (fieldCharSet == &my_charset_bin) // If binary
- {
- if (bytesToStore)
- memcpy(db2Buf, dataToStore, bytesToStore);
- if (bytesToPad)
- memset(db2Buf + bytesToStore, 0x00, bytesToPad);
- }
- else if (db2Field.getCCSID() == 1208) // utf8
- {
- if (bytesToStore)
- memcpy(db2Buf, dataToStore, bytesToStore);
- if (bytesToPad)
- memset(db2Buf + bytesToStore, ' ', bytesToPad);
- }
- else // single-byte ASCII to EBCDIC
- {
- DBUG_ASSERT(fieldCharSet->mbmaxlen == 1);
- if (bytesToStore)
- {
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore, db2Buf, bytesToStore, bytesToStore, NULL);
- if (rc)
- return rc;
- }
- if (bytesToPad)
- memset(db2Buf + bytesToStore, 0x40, bytesToPad);
- }
-
- if (db2FieldType == QMY_VARCHAR)
- *(uint16*)(db2Buf - sizeof(uint16)) = bytesToStore;
- break;
- case QMY_VARGRAPHIC:
- db2Buf += sizeof(uint16);
- bytesToPad = 0;
- case QMY_GRAPHIC:
- if (maxDisplayLength == 0 && db2FieldType == QMY_GRAPHIC)
- bytesToPad = 2;
-
- if (db2Field.getCCSID() == 13488)
- {
- if (bytesToStore)
- memcpy(db2Buf, dataToStore, bytesToStore);
- if (bytesToPad)
- memset16((db2Buf + bytesToStore), 0x0020, bytesToPad/2);
- }
- else
- {
- size_t db2BytesToStore;
- size_t maxDb2BytesToStore;
-
- if (maxDisplayLength == 0 && db2FieldType == QMY_GRAPHIC)
- maxDb2BytesToStore = 2;
- else
- maxDb2BytesToStore = min(((bytesToStore * 2) / fieldCharSet->mbminlen),
- ((maxDisplayLength * 2) / fieldCharSet->mbmaxlen));
-
- if (bytesToStore == 0)
- db2BytesToStore = 0;
- else
- {
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore, db2Buf, bytesToStore, maxDb2BytesToStore, &db2BytesToStore);
- if (rc)
- return rc;
- bytesToStore = db2BytesToStore;
- }
- if (db2BytesToStore < maxDb2BytesToStore) // If need to pad
- memset16((db2Buf + db2BytesToStore), 0x0020, (maxDb2BytesToStore - db2BytesToStore)/2);
- }
-
- if (db2FieldType == QMY_VARGRAPHIC)
- *(uint16*)(db2Buf-sizeof(uint16)) = bytesToStore/2;
- break;
- case QMY_BLOBCLOB:
- case QMY_DBCLOB:
- {
- DBUG_ASSERT(data == NULL);
- DB2LobField* lobField = (DB2LobField*)(db2Buf + db2Field.calcBlobPad());
-
- if ((fieldCharSet == &my_charset_bin) || // binary or
- (db2Field.getCCSID()==13488) ||
- (db2Field.getCCSID()==1208)) // binary UTF8
- {
- }
- else
- {
- char* temp;
- int32 rc;
- size_t db2BytesToStore;
- if (fieldCharSet->mbmaxlen == 1) // single-byte ASCII to EBCDIC
- {
- temp = getCharacterConversionBuffer(field->field_index, bytesToStore);
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore,temp,bytesToStore, bytesToStore, NULL);
- if (rc)
- return (rc);
- }
- else // Else Far East, special UTF8 or non-special UTF8/UCS2
- {
- size_t maxDb2BytesToStore;
- maxDb2BytesToStore = min(((bytesToStore * 2) / fieldCharSet->mbminlen),
- ((maxDisplayLength * 2) / fieldCharSet->mbmaxlen));
- temp = getCharacterConversionBuffer(field->field_index, maxDb2BytesToStore);
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore,temp,bytesToStore, maxDb2BytesToStore, &db2BytesToStore);
- if (rc)
- return (rc);
- bytesToStore = db2BytesToStore;
- }
- dataToStore = (uchar*)temp;
- }
-
- uint16 blobID = db2Table->getBlobIdFromField(field->field_index);
- if (blobWriteBuffers[blobID] != (char*)dataToStore)
- blobWriteBuffers[blobID].reassign((char*)dataToStore);
- if ((void*)blobWriteBuffers[blobID])
- lobField->dataHandle = (ILEMemHandle)blobWriteBuffers[blobID];
- else
- lobField->dataHandle = 0;
- lobField->length = bytesToStore / (db2FieldType == QMY_DBCLOB ? 2 : 1);
- }
- break;
- }
- }
- }
- break;
- default:
- DBUG_ASSERT(0);
- break;
- }
-
- return (ha_thd()->is_error());
-}
-
-
-/**
- Convert DB2 field data into the equivalent MySQL format
-
- @param db2Field The DB2 field definition
- @param field The MySQL field to receive the converted data
- @param buf The DB2 data to be converted
-*/
-int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, const char* buf)
-{
- int32 storeRC = 0; // Result of the field->store() operation
-
- const char* bufPtr = buf + db2Field.getBufferOffset();
-
- switch (field->type())
- {
- case MYSQL_TYPE_NEWDECIMAL:
- {
- uint precision= ((Field_new_decimal*)field)->precision;
- uint scale= field->decimals();
- uint db2Precision = min(precision, MAX_DEC_PRECISION);
- uint decimalPlace = precision-scale+1;
- char temp[80];
-
- if (precision <= MAX_DEC_PRECISION ||
- scale > precision - MAX_DEC_PRECISION)
- {
- uint numNibbles = db2Precision + (db2Precision % 2 ? 0 : 1);
-
- temp[0] = (bcdGet(bufPtr, numNibbles) == 0xD ? '-' : ' ');
- int strPos=1;
- int bcdPos=(db2Precision % 2 ? 0 : 1);
-
- for (;bcdPos < numNibbles; bcdPos++, strPos++)
- {
- if (strPos == decimalPlace)
- {
- temp[strPos] = '.';
- strPos++;
- }
-
- temp[strPos] = bcdGet(bufPtr, bcdPos) + '0';
- }
-
- temp[strPos] = 0;
-
- storeRC = field->store(temp, strPos, &my_charset_latin1);
- }
- }
- break;
- case MYSQL_TYPE_TINY:
- {
- storeRC = field->store(*(int16*)bufPtr, ((Field_num*)field)->unsigned_flag);
- }
- break;
- case MYSQL_TYPE_SHORT:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- storeRC = field->store(*(int32*)bufPtr, TRUE);
- }
- else
- {
- storeRC = field->store(*(int16*)bufPtr, FALSE);
- }
- }
- break;
- case MYSQL_TYPE_LONG:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- storeRC = field->store(*(int64*)bufPtr, TRUE);
- }
- else
- {
- storeRC = field->store(*(int32*)bufPtr, FALSE);
- }
- }
- break;
- case MYSQL_TYPE_FLOAT:
- {
- storeRC = field->store(*(float*)bufPtr);
- }
- break;
- case MYSQL_TYPE_DOUBLE:
- {
- storeRC = field->store(*(double*)bufPtr);
- }
- break;
- case MYSQL_TYPE_LONGLONG:
- {
- char temp[23];
- if (((Field_num*)field)->unsigned_flag)
- {
- temp[0] = (bcdGet(bufPtr, 21) == 0xD ? '-' : ' ');
- int strPos=1;
- int bcdPos=0;
-
- for (;bcdPos <= 20; bcdPos++, strPos++)
- {
- temp[strPos] = bcdGet(bufPtr, bcdPos) + '0';
- }
-
- temp[strPos] = 0;
-
- storeRC = field->store(temp, strPos, &my_charset_latin1);
- }
- else
- {
- storeRC = field->store(*(int64*)bufPtr, FALSE);
- }
- }
- break;
- case MYSQL_TYPE_INT24:
- {
- storeRC = field->store(*(int32*)bufPtr, ((Field_num*)field)->unsigned_flag);
- }
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- {
- longlong value= a4toi_ebcdic((uchar*)bufPtr) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+5) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+8);
-
- if (cachedZeroDateOption == SUBSTITUTE_0001_01_01 &&
- value == (10000 + 100 + 1))
- value = 0;
-
- storeRC = field->store(value);
- }
- break;
- case MYSQL_TYPE_TIME:
- {
- if (db2Field.getType() == QMY_TIME)
- {
- longlong value= a2toi_ebcdic((uchar*)bufPtr) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+3) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+6);
-
- storeRC = field->store(value);
- }
- else
- storeRC = field->store(*((int32*)bufPtr));
- }
- break;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATETIME:
- {
- longlong value= (a4toi_ebcdic((uchar*)bufPtr) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+5) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+8)) * 1000000LL +
- (a2toi_ebcdic((uchar*)bufPtr+11) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+14) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+17));
-
- if (cachedZeroDateOption == SUBSTITUTE_0001_01_01 &&
- value == (10000 + 100 + 1) * 1000000LL)
- value = 0;
-
- storeRC = field->store(value);
- }
- break;
- case MYSQL_TYPE_YEAR:
- {
- if (db2Field.getType() == QMY_CHAR)
- {
- storeRC = field->store(bufPtr, 4, &my_charset_bin);
- }
- else
- {
- storeRC = field->store(*((uint16*)bufPtr));
- }
- }
- break;
- case MYSQL_TYPE_BIT:
- {
- uint64 temp= 0;
- int bytesToCopy= db2Field.getByteLengthInRecord();
- memcpy(((char*)&temp) + (sizeof(temp) - bytesToCopy), bufPtr, bytesToCopy);
- storeRC = field->store(temp, TRUE);
- }
- break;
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_BLOB:
- {
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- storeRC = field->store(*(int64*)bufPtr);
- }
- else
- {
-
- const char* dataToStore = NULL;
- uint32 bytesToStore = 0;
- CHARSET_INFO* fieldCharSet = field->charset();
- switch(db2Field.getType())
- {
- case QMY_CHAR:
- case QMY_GRAPHIC:
- {
- bytesToStore = db2Field.getByteLengthInRecord();
- if (bytesToStore == 0)
- bytesToStore = 1;
- dataToStore = bufPtr;
- }
- break;
- case QMY_VARCHAR:
- {
- bytesToStore = *(uint16*)bufPtr;
- dataToStore = bufPtr+sizeof(uint16);
- }
- break;
- case QMY_VARGRAPHIC:
- {
- /* For VARGRAPHIC, convert the number of double-byte characters
- to the number of bytes. */
- bytesToStore = (*(uint16*)bufPtr)*2;
- dataToStore = bufPtr+sizeof(uint16);
- }
- break;
- case QMY_DBCLOB:
- case QMY_BLOBCLOB:
- {
- DB2LobField* lobField = (DB2LobField* )(bufPtr + db2Field.calcBlobPad());
- bytesToStore = lobField->length * (db2Field.getType() == QMY_DBCLOB ? 2 : 1);
- dataToStore = (char*)blobReadBuffers->getBufferPtr(field->field_index);
- }
- break;
-
- }
-
- if ((fieldCharSet != &my_charset_bin) && // not binary &
- (db2Field.getCCSID() != 13488) && // not UCS2 &
- (db2Field.getCCSID() != 1208))
- {
- char* temp;
- size_t db2BytesToStore;
- int rc;
- if (fieldCharSet->mbmaxlen > 1)
- {
- size_t maxDb2BytesToStore = ((bytesToStore / 2) * fieldCharSet->mbmaxlen); // Worst case for number of bytes
- temp = getCharacterConversionBuffer(field->field_index, maxDb2BytesToStore);
- rc = convertFieldChars(toMySQL, field->field_index, dataToStore, temp, bytesToStore, maxDb2BytesToStore, &db2BytesToStore);
- bytesToStore = db2BytesToStore;
- }
- else // single-byte ASCII to EBCDIC
- {
- temp = getCharacterConversionBuffer(field->field_index, bytesToStore);
- rc = convertFieldChars(toMySQL, field->field_index, dataToStore, temp, bytesToStore, bytesToStore, NULL);
- }
- if (rc)
- return (rc);
- dataToStore = temp;
- }
-
- if ((field)->flags & BLOB_FLAG)
- ((Field_blob*)(field))->set_ptr(bytesToStore, (uchar*)dataToStore);
- else
- storeRC = field->store(dataToStore, bytesToStore, &my_charset_bin);
- }
- }
- break;
- default:
- DBUG_ASSERT(0);
- break;
-
- }
-
- if (storeRC)
- {
- invalidDataFound = true;
- }
-
- return 0;
-}
diff --git a/storage/ibmdb2i/db2i_errors.cc b/storage/ibmdb2i/db2i_errors.cc
deleted file mode 100644
index dd50e40e61b..00000000000
--- a/storage/ibmdb2i/db2i_errors.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_errors.h"
-#include "db2i_ileBridge.h"
-#include "db2i_charsetSupport.h"
-#include "mysql_priv.h"
-#include "stdarg.h"
-
-#define MAX_MSGSTRING 109
-
-/*
- The following strings are associated with errors that can be produced
- within the storage engine proper.
-*/
-static const char* engineErrors[MAX_MSGSTRING] =
-{
- {""},
- {"Error opening codeset conversion from %.64s to %.64s (errno = %d)"},
- {"Invalid %-.10s name '%-.128s'"},
- {"Unsupported move from '%-.128s' to '%-.128s' on RENAME TABLE statement"},
- {"The %-.64s character set is not supported."},
- {"Auto_increment is not allowed for a partitioned table"},
- {"Character set conversion error due to unknown encoding scheme %d"},
- {""},
- {"Table '%-.128s' was not found by the storage engine"},
- {"Could not resolve to %-.128s in library %-.10s type %-.10s (errno = %d)"},
- {"Error on _PGMCALL for program %-.10s in library %-.10s (error = %d)"},
- {"Error on _ILECALL for API '%.128s' (error = %d)"},
- {"Error in iconv() function during character set conversion (errno = %d)"},
- {"Error from Get Encoding Scheme (QTQGESP) API: %d, %d, %d"},
- {"Error from Get Related Default CCSID (QTQGRDC) API: %d, %d, %d"},
- {"Data out of range for column '%.192s'"},
- {"Schema name '%.128s' exceeds maximum length of %d characters"},
- {"Multiple collations not supported in a single index or constraint"},
- {"Sort sequence was not found"},
- {"One or more characters in column %.128s were substituted during conversion"},
- {"A decimal column exceeded the maximum precision. Data may be truncated."},
- {"Some data returned by DB2 for table %s could not be converted for MySQL"},
- {""},
- {"Column %.128s contains characters that cannot be converted"},
- {"An invalid name was specified for ibmdb2i_rdb_name."},
- {"A duplicate key was encountered for index '%.128s'"},
- {"A table with the same name exists but has incompatible column definitions."},
- {"The created table was discovered as an existing DB2 object."},
- {"Some attribute(s) defined for column '%.128s' may not be honored by accesses from DB2."},
-};
-
-/*
- The following strings are associated with errors that can be returned
- by the operating system via the QMY_* APIs. Most are very uncommon and
- indicate a bug somewhere.
-*/
-static const char* systemErrors[MAX_MSGSTRING] =
-{
- {"Thread ID is too long"},
- {"Error creating a SPACE memory object"},
- {"Error creating a FILE memory object"},
- {"Error creating a SPACE synchronization token"},
- {"Error creating a FILE synchronization token"},
- {"See message %-.7s in joblog for job %-.6s/%-.10s/%-.10s."},
- {"Error unlocking a synchronization token when closing a connection"},
- {"Invalid action specified for an 'object lock' request"},
- {"Invalid action specified for a savepoint request"},
- {"Partial keys are not supported with an ICU sort sequence"},
- {"Error retrieving an ICU sort key"},
- {"Error converting single-byte sort sequence to UCS-2"},
- {"An unsupported collation was specified"},
- {"Validation failed for referenced table of foreign key constraint"},
- {"Error extracting table for constraint information"},
- {"Error extracting referenced table for constraint information"},
- {"Invalid action specified for a 'commitment control' request"},
- {"Invalid commitment control isolation level specified on 'open' request"},
- {"Invalid file handle"},
- {" "},
- {"Invalid option specified for returning data on 'read' request"},
- {"Invalid orientation specified for 'read' request"},
- {"Invalid option type specified for 'read' request"},
- {"Invalid isolation level for starting commitment control"},
- {"Error unlocking a synchronization token in module QMYALC"},
- {"Length of space for returned format is not long enough"},
- {"SQL XA transactions are currently unsupported by this interface"},
- {"The associated QSQSRVR job was killed or ended unexpectedly."},
- {"Error unlocking a synchronization token in module QMYSEI"},
- {"Error unlocking a synchronization token in module QMYSPO"},
- {"Error converting input CCSID from short form to long form"},
- {" "},
- {"Error getting associated CCSID for CCSID conversion"},
- {"Error converting a string from one CCSID to another"},
- {"Error unlocking a synchronization token"},
- {"Error destroying a synchronization token"},
- {"Error locking a synchronization token"},
- {"Error recreating a synchronization token"},
- {"A space handle was not specified for a constraint request"},
- {"An SQL cursor was specified for a delete request"},
- {" "},
- {"Error on delete request because current UFCB for connection is not open"},
- {"An SQL cursor was specified for an object initialization request"},
- {"An SQL cursor was specified for an object override request"},
- {"A space handle was not specified for an object override request"},
- {"An SQL cursor was specified for an information request"},
- {"An SQL cursor was specified for an object lock request"},
- {"An SQL cursor was specified for an optimize request"},
- {"A data handle was not specified for a read request"},
- {"A row number handle was not specified for a read request"},
- {"A key handle was not specified for a read request"},
- {"An SQL cursor was specified for an row estimation request"},
- {"A space handle was not specified for a row estimation request"},
- {"An SQL cursor was specified for a release record request"},
- {"A statement handle was not specified for an 'execute immediate' request"},
- {"A statement handle was not specified for a 'prepare open' request"},
- {"An SQL cursor was specified for an update request"},
- {"The UFCB was not open for read"},
- {"Error on update request because current UFCB for connection is not open"},
- {"A data handle was not specified for an update request"},
- {"An SQL cursor was specified for a write request"},
- {"A data handle was not specified for a write request"},
- {"An unknown function was specified on a process request"},
- {"A share definition was not specified for an 'allocate share' request"},
- {"A share handle was not specified for an 'allocate share' request"},
- {"A use count handle was not specified for an 'allocate share' request"},
- {"A 'records per key' handle was not specified for an information request"},
- {"Error resolving LOB addresss"},
- {"Length of a LOB space is too small"},
- {"An unknown function was specified for a server request"},
- {"Object authorization failed. See message %-.7s in joblog for job %-.6s/%-.10s/%-.10s. for more information."},
- {" "},
- {"Error locking mutex on server"},
- {"Error unlocking mutex on server"},
- {"Error checking for RDB name in RDB Directory"},
- {"Error creating mutex on server"},
- {"A table with that name already exists"},
- {" "},
- {"Error unlocking mutex"},
- {"Error connecting to server job"},
- {"Error connecting to server job"},
- {" "},
- {"Function check occurred while registering parameter spaces. See joblog."},
- {" "},
- {" "},
- {"End of block"},
- {"The file has changed and might not be compatible with the MySQL table definition"},
- {"Error giving pipe to server job"},
- {"There are open object locks when attempting to deallocate"},
- {"There is no open lock"},
- {" "},
- {" "},
- {"The maximum value for the auto_increment data type was exceeded"},
- {"Error occurred closing the pipe "},
- {"Error occurred taking a descriptor for the pipe"},
- {"Error writing to pipe "},
- {"Server was interrupted "},
- {"No pipe descriptor exists for reuse "},
- {"Error occurred during an SQL prepare statement "},
- {"Error occurred during an SQL open "},
- {" "},
- {" "},
- {" "},
- {" "},
- {" "},
- {" "},
- {"An unspecified error was returned from the system."},
- {" "}
-};
-
-/**
- This function builds the text string for an error code, and substitutes
- a variable number of replacement variables into the string.
-*/
-void getErrTxt(int errCode, ...)
-{
- va_list args;
- va_start(args,errCode);
- char* buffer = db2i_ileBridge::getBridgeForThread()->getErrorStorage();
- const char* msg;
-
- if (errCode >= QMY_ERR_MIN && errCode <= QMY_ERR_SQ_OPEN)
- msg = systemErrors[errCode - QMY_ERR_MIN];
- else
- {
- DBUG_ASSERT(errCode >= DB2I_FIRST_ERR && errCode <= DB2I_LAST_ERR);
- msg = engineErrors[errCode - DB2I_FIRST_ERR];
- }
-
- (void) my_vsnprintf (buffer, MYSQL_ERRMSG_SIZE, msg, args);
- va_end(args);
- fprintf(stderr,"ibmdb2i error %d: %s\n",errCode,buffer);
- DBUG_PRINT("error", ("ibmdb2i error %d: %s",errCode,buffer));
-}
-
-static inline void trimSpace(char* str)
-{
- char* end = strchr(str, ' ');
- if (end) *end = 0;
-}
-
-
-/**
- Generate the error text specific to an API error returned by a QMY_* API.
-
- @parm errCode The error value
- @parm errInfo The structure containing the message and job identifiers.
-*/
-void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo)
-{
- if (errCode >= QMY_ERR_MIN && errCode <= QMY_ERR_SQ_OPEN)
- {
- switch(errCode)
- {
- case QMY_ERR_MSGID:
- case QMY_ERR_NOT_AUTH:
- {
- DBUG_ASSERT(errInfo);
- char jMsg[8]; // Error message ID
- char jName[11]; // Job name
- char jUser[11]; // Job user
- char jNbr[7]; // Job number
- memset(jMsg, 0, sizeof(jMsg));
- memset(jName, 0, sizeof(jMsg));
- memset(jUser, 0, sizeof(jMsg));
- memset(jMsg, 0, sizeof(jMsg));
-
- convFromEbcdic(errInfo->MsgId,jMsg,sizeof(jMsg)-1);
- convFromEbcdic(errInfo->JobName,jName,sizeof(jName)-1);
- trimSpace(jName);
- convFromEbcdic(errInfo->JobUser,jUser,sizeof(jUser)-1);
- trimSpace(jUser);
- convFromEbcdic(errInfo->JobNbr,jNbr,sizeof(jNbr)-1);
- getErrTxt(errCode,jMsg,jNbr,jUser,jName);
- }
- break;
- case QMY_ERR_RTNFMT:
- {
- getErrTxt(QMY_ERR_LVLID_MISMATCH);
- }
- break;
- default:
- getErrTxt(errCode);
- break;
- }
- }
-}
-
-
-/**
- Generate a warning for the specified error.
-*/
-void warning(THD *thd, int errCode, ...)
-{
- va_list args;
- va_start(args,errCode);
- char buffer[MYSQL_ERRMSG_SIZE];
- const char* msg;
-
- DBUG_ASSERT(errCode >= DB2I_FIRST_ERR && errCode <= DB2I_LAST_ERR);
- msg = engineErrors[errCode - DB2I_FIRST_ERR];
-
- (void) my_vsnprintf (buffer, MYSQL_ERRMSG_SIZE, msg, args);
- va_end(args);
- DBUG_PRINT("warning", ("ibmdb2i warning %d: %s",errCode,buffer));
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, errCode, buffer);
-}
-
-
diff --git a/storage/ibmdb2i/db2i_errors.h b/storage/ibmdb2i/db2i_errors.h
deleted file mode 100644
index b6dd314ef50..00000000000
--- a/storage/ibmdb2i/db2i_errors.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_ERRORS_H
-#define DB2I_ERRORS_H
-
-#include "qmyse.h"
-class THD;
-
-/**
- @enum DB2I_errors
-
- @brief These are the errors that can be returned by the storage engine proper
- and that are specific to the engine. Refer to db2i_errors.cc for text
- descriptions of the errors.
-*/
-
-enum DB2I_errors
-{
- DB2I_FIRST_ERR = 2500,
- DB2I_ERR_ICONV_OPEN,
- DB2I_ERR_INVALID_NAME,
- DB2I_ERR_RENAME_MOVE,
- DB2I_ERR_UNSUPP_CHARSET,
- DB2I_ERR_PART_AUTOINC,
- DB2I_ERR_UNKNOWN_ENCODING,
- DB2I_ERR_RESERVED,
- DB2I_ERR_TABLE_NOT_FOUND,
- DB2I_ERR_RESOLVE_OBJ,
- DB2I_ERR_PGMCALL,
- DB2I_ERR_ILECALL,
- DB2I_ERR_ICONV,
- DB2I_ERR_QTQGESP,
- DB2I_ERR_QTQGRDC,
- DB2I_ERR_INVALID_COL_VALUE,
- DB2I_ERR_TOO_LONG_SCHEMA,
- DB2I_ERR_MIXED_COLLATIONS,
- DB2I_ERR_SRTSEQ,
- DB2I_ERR_SUB_CHARS,
- DB2I_ERR_PRECISION,
- DB2I_ERR_INVALID_DATA,
- DB2I_ERR_RESERVED2,
- DB2I_ERR_ILL_CHAR,
- DB2I_ERR_BAD_RDB_NAME,
- DB2I_ERR_UNKNOWN_IDX,
- DB2I_ERR_DISCOVERY_MISMATCH,
- DB2I_ERR_WARN_CREATE_DISCOVER,
- DB2I_ERR_WARN_COL_ATTRS,
- DB2I_LAST_ERR = DB2I_ERR_WARN_COL_ATTRS
-};
-
-void getErrTxt(int errcode, ...);
-void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo);
-void warning(THD *thd, int errCode, ...);
-
-const char* DB2I_SQL0350 = "\xE2\xD8\xD3\xF0\xF3\xF5\xF0"; // SQL0350 in EBCDIC
-const char* DB2I_CPF503A = "\xC3\xD7\xC6\xF5\xF0\xF3\xC1"; // CPF503A in EBCDIC
-const char* DB2I_SQL0538 = "\xE2\xD8\xD3\xF0\xF5\xF3\xF8"; // SQL0538 in EBCDIC
-
-#endif
diff --git a/storage/ibmdb2i/db2i_file.cc b/storage/ibmdb2i/db2i_file.cc
deleted file mode 100644
index a16aa927527..00000000000
--- a/storage/ibmdb2i/db2i_file.cc
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_file.h"
-#include "db2i_charsetSupport.h"
-#include "db2i_collationSupport.h"
-#include "db2i_misc.h"
-#include "db2i_errors.h"
-#include "my_dir.h"
-
-db2i_table::db2i_table(const TABLE_SHARE* myTable, const char* path) :
- mysqlTable(myTable),
- db2StartId(0),
- blobFieldCount(0),
- blobFields(NULL),
- blobFieldActualSizes(NULL),
- logicalFiles(NULL),
- physicalFile(NULL),
- db2TableNameSQLAscii(NULL),
- db2LibNameSQLAscii(NULL)
-{
- char asciiLibName[MAX_DB2_SCHEMANAME_LENGTH + 1];
- getDB2LibNameFromPath(path, asciiLibName, ASCII_NATIVE);
-
- char asciiFileName[MAX_DB2_FILENAME_LENGTH + 1];
- getDB2FileNameFromPath(path, asciiFileName, ASCII_NATIVE);
-
- size_t libNameLen = strlen(asciiLibName);
- size_t fileNameLen = strlen(asciiFileName);
-
- db2LibNameEbcdic=(char *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &db2LibNameEbcdic, libNameLen+1,
- &db2LibNameAscii, libNameLen+1,
- &db2LibNameSQLAscii, libNameLen*2 + 1,
- &db2TableNameEbcdic, fileNameLen+1,
- &db2TableNameAscii, fileNameLen+1,
- &db2TableNameSQLAscii, fileNameLen*2 + 1,
- NullS);
-
- if (likely(db2LibNameEbcdic))
- {
- memcpy(db2LibNameAscii, asciiLibName, libNameLen);
- convertNativeToSQLName(db2LibNameAscii, db2LibNameSQLAscii);
- convToEbcdic(db2LibNameAscii, db2LibNameEbcdic, libNameLen);
- memcpy(db2TableNameAscii, asciiFileName, fileNameLen);
- convertNativeToSQLName(db2TableNameAscii, db2TableNameSQLAscii);
- convToEbcdic(db2TableNameAscii, db2TableNameEbcdic, fileNameLen);
- }
-
- conversionDefinitions[toMySQL] = NULL;
- conversionDefinitions[toDB2] = NULL;
-
- isTemporaryTable = (strstr(mysqlTable->path.str, mysql_tmpdir) == mysqlTable->path.str);
-}
-
-
-int32 db2i_table::initDB2Objects(const char* path)
-{
- uint fileObjects = 1 + mysqlTable->keys;
- ValidatedPointer<ShrDef> fileDefnSpace(sizeof(ShrDef) * fileObjects);
-
- physicalFile = new db2i_file(this);
- physicalFile->fillILEDefn(&fileDefnSpace[0], true);
-
- logicalFileCount = mysqlTable->keys;
- if (logicalFileCount > 0)
- {
- logicalFiles = new db2i_file*[logicalFileCount];
- for (int k = 0; k < logicalFileCount; k++)
- {
- logicalFiles[k] = new db2i_file(this, k);
- logicalFiles[k]->fillILEDefn(&fileDefnSpace[k+1], false);
- }
- }
-
- ValidatedPointer<FILE_HANDLE> fileDefnHandles(sizeof(FILE_HANDLE) * fileObjects);
- size_t formatSpaceLen = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field);
- formatSpace.alloc(formatSpaceLen);
-
- int rc = db2i_ileBridge::getBridgeForThread()->
- expectErrors(QMY_ERR_RTNFMT)->
- allocateFileDefn(fileDefnSpace,
- fileDefnHandles,
- fileObjects,
- db2LibNameEbcdic,
- strlen(db2LibNameEbcdic),
- formatSpace,
- formatSpaceLen);
-
- if (rc)
- {
- // We have to handle a format space error as a special case of a FID
- // mismatch. We should only get the space error if columns have been added
- // to the DB2 table without MySQL's knowledge, which is effectively a
- // FID problem.
- if (rc == QMY_ERR_RTNFMT)
- {
- rc = QMY_ERR_LVLID_MISMATCH;
- getErrTxt(rc);
- }
- return rc;
- }
-
- convFromEbcdic(((format_hdr_t*)formatSpace)->FilLvlId, fileLevelID, sizeof(fileLevelID));
-
- if (!doFileIDsMatch(path))
- {
- getErrTxt(QMY_ERR_LVLID_MISMATCH);
- return QMY_ERR_LVLID_MISMATCH;
- }
-
- physicalFile->setMasterDefnHandle(fileDefnHandles[0]);
- for (int k = 0; k < mysqlTable->keys; k++)
- {
- logicalFiles[k]->setMasterDefnHandle(fileDefnHandles[k+1]);
- }
-
- db2StartId = (uint64)(((format_hdr_t*)formatSpace)->StartIdVal);
- db2Fields = (DB2Field*)((char*)(void*)formatSpace + ((format_hdr_t*)formatSpace)->ColDefOff);
-
- uint fields = mysqlTable->fields;
- for (int i = 0; i < fields; ++i)
- {
- if (db2Field(i).isBlob())
- {
- blobFieldCount++;
- }
- }
-
- if (blobFieldCount)
- {
- blobFieldActualSizes = (uint*)my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &blobFieldActualSizes, blobFieldCount * sizeof(uint),
- &blobFields, blobFieldCount * sizeof(uint16),
- NullS);
-
- int b = 0;
- for (int i = 0; i < fields; ++i)
- {
- if (db2Field(i).isBlob())
- {
- blobFields[b++] = i;
- }
- }
- }
-
- my_multi_malloc(MYF(MY_WME),
- &conversionDefinitions[toMySQL], fields * sizeof(iconv_t),
- &conversionDefinitions[toDB2], fields * sizeof(iconv_t),
- NullS);
- for (int i = 0; i < fields; ++i)
- {
- conversionDefinitions[toMySQL][i] = (iconv_t)(-1);
- conversionDefinitions[toDB2][i] = (iconv_t)(-1);
- }
-
- return 0;
-}
-
-int db2i_table::fastInitForCreate(const char* path)
-{
- ValidatedPointer<ShrDef> fileDefnSpace(sizeof(ShrDef));
-
- physicalFile = new db2i_file(this);
- physicalFile->fillILEDefn(fileDefnSpace, true);
-
- ValidatedPointer<FILE_HANDLE> fileDefnHandles(sizeof(FILE_HANDLE));
-
- size_t formatSpaceLen = sizeof(format_hdr_t) +
- mysqlTable->fields * sizeof(DB2Field);
- formatSpace.alloc(formatSpaceLen);
-
- int rc = db2i_ileBridge::getBridgeForThread()->allocateFileDefn(fileDefnSpace,
- fileDefnHandles,
- 1,
- db2LibNameEbcdic,
- strlen(db2LibNameEbcdic),
- formatSpace,
- formatSpaceLen);
-
- if (rc)
- return rc;
-
- convFromEbcdic(((format_hdr_t*)formatSpace)->FilLvlId, fileLevelID, sizeof(fileLevelID));
- doFileIDsMatch(path);
-
- return 0;
-}
-
-bool db2i_table::doFileIDsMatch(const char* path)
-{
- char name_buff[FN_REFLEN];
-
- fn_format(name_buff, path, "", FID_EXT, (MY_REPLACE_EXT | MY_UNPACK_FILENAME));
-
- File fd = my_open(name_buff, O_RDONLY, MYF(0));
-
- if (fd == -1)
- {
- if (errno == ENOENT)
- {
- fd = my_create(name_buff, 0, O_WRONLY, MYF(MY_WME));
-
- if (fd == -1)
- {
- // TODO: Report errno here
- return false;
- }
- my_write(fd, (uchar*)fileLevelID, sizeof(fileLevelID), MYF(MY_WME));
- my_close(fd, MYF(0));
- return true;
- }
- else
- {
- // TODO: Report errno here
- return false;
- }
- }
-
- char diskFID[sizeof(fileLevelID)];
-
- bool match = false;
-
- if (my_read(fd, (uchar*)diskFID, sizeof(diskFID), MYF(MY_WME)) == sizeof(diskFID) &&
- (memcmp(diskFID, fileLevelID, sizeof(diskFID)) == 0))
- match = true;
-
- my_close(fd, MYF(0));
-
- return match;
-}
-
-void db2i_table::deleteAssocFiles(const char* name)
-{
- char name_buff[FN_REFLEN];
- fn_format(name_buff, name, "", FID_EXT, (MY_REPLACE_EXT | MY_UNPACK_FILENAME));
- my_delete(name_buff, MYF(0));
-}
-
-void db2i_table::renameAssocFiles(const char* from, const char* to)
-{
- rename_file_ext(from, to, FID_EXT);
-}
-
-
-db2i_table::~db2i_table()
-{
- if (blobFieldActualSizes)
- my_free(blobFieldActualSizes, MYF(0));
-
- if (conversionDefinitions[toMySQL])
- my_free(conversionDefinitions[toMySQL], MYF(0));
-
- if (logicalFiles)
- {
- for (int k = 0; k < logicalFileCount; ++k)
- {
- delete logicalFiles[k];
- }
-
- delete[] logicalFiles;
- }
- delete physicalFile;
-
- my_free(db2LibNameEbcdic, 0);
-}
-
-void db2i_table::getDB2QualifiedName(char* to)
-{
- strcat(to, getDB2LibName(ASCII_SQL));
- strcat(to, ".");
- strcat(to, getDB2TableName(ASCII_SQL));
-}
-
-
-void db2i_table::getDB2QualifiedNameFromPath(const char* path, char* to)
-{
- getDB2LibNameFromPath(path, to);
- strcat(to, ".");
- getDB2FileNameFromPath(path, strend(to));
-}
-
-
-size_t db2i_table::smartFilenameToTableName(const char *in, char* out, size_t outlen)
-{
- if (strchr(in, '@') == NULL)
- {
- return filename_to_tablename(in, out, outlen);
- }
-
- char* test = (char*) my_malloc(outlen, MYF(MY_WME));
-
- filename_to_tablename(in, test, outlen);
-
- char* cur = test;
-
- while (*cur)
- {
- if ((*cur <= 0x20) || (*cur >= 0x80))
- {
- strncpy(out, in, outlen);
- my_free(test, MYF(0));
- return min(outlen, strlen(out));
- }
- ++cur;
- }
-
- strncpy(out, test, outlen);
- my_free(test, MYF(0));
- return min(outlen, strlen(out));
-}
-
-void db2i_table::filenameToTablename(const char* in, char* out, size_t outlen)
-{
- if (strchr(in, '#') == NULL)
- {
- smartFilenameToTableName(in, out, outlen);
- return;
- }
-
- char* temp = (char*)sql_alloc(outlen);
-
- const char* part1, *part2, *part3, *part4;
- part1 = in;
- part2 = strstr(part1, "#P#");
- if (part2);
- {
- part3 = part2 + 3;
- part4 = strchr(part3, '#');
- if (!part4)
- part4 = strend(in);
- }
-
- memcpy(temp, part1, min(outlen, part2 - part1));
- temp[min(outlen-1, part2-part1)] = 0;
-
- int32 accumLen = smartFilenameToTableName(temp, out, outlen);
-
- if (part2 && (accumLen + 4 < outlen))
- {
- strcat(out, "#P#");
- accumLen += 4;
-
- memset(temp, 0, min(outlen, part2-part1));
- memcpy(temp, part3, min(outlen, part4-part3));
- temp[min(outlen-1, part4-part3)] = 0;
-
- accumLen += smartFilenameToTableName(temp, strend(out), outlen-accumLen);
-
- if (part4 && (accumLen + (strend(in) - part4 + 1) < outlen))
- {
- strcat(out, part4);
- }
- }
-}
-
-void db2i_table::getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format)
-{
- if (strstr(path, mysql_tmpdir) == path)
- {
- strcpy(lib, DB2I_TEMP_TABLE_SCHEMA);
- }
- else
- {
- const char* c = strend(path) - 1;
- while (c > path && *c != '\\' && *c != '/')
- --c;
-
- if (c != path)
- {
- const char* dbEnd = c;
- do {
- --c;
- } while (c >= path && *c != '\\' && *c != '/');
-
- if (c >= path)
- {
- const char* dbStart = c+1;
- char fileName[FN_REFLEN];
- memcpy(fileName, dbStart, dbEnd - dbStart);
- fileName[dbEnd-dbStart] = 0;
-
- char dbName[MAX_DB2_SCHEMANAME_LENGTH+1];
- filenameToTablename(fileName, dbName , sizeof(dbName));
-
- convertMySQLNameToDB2Name(dbName, lib, sizeof(dbName), true, (format==ASCII_SQL) );
- }
- else
- DBUG_ASSERT(0); // This should never happen!
- }
- }
-}
-
-void db2i_table::getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format)
-{
- const char* fileEnd = strend(path);
- const char* c = fileEnd;
- while (c > path && *c != '\\' && *c != '/')
- --c;
-
- if (c != path)
- {
- const char* fileStart = c+1;
- char fileName[FN_REFLEN];
- memcpy(fileName, fileStart, fileEnd - fileStart);
- fileName[fileEnd - fileStart] = 0;
- char db2Name[MAX_DB2_FILENAME_LENGTH+1];
- filenameToTablename(fileName, db2Name, sizeof(db2Name));
- convertMySQLNameToDB2Name(db2Name, file, sizeof(db2Name), true, (format==ASCII_SQL) );
- }
-}
-
-// Generates the DB2 index name when given the MySQL index and table names.
-int32 db2i_table::appendQualifiedIndexFileName(const char* indexName,
- const char* tableName,
- String& to,
- NameFormatFlags format,
- enum_DB2I_INDEX_TYPE type)
-{
- char generatedName[MAX_DB2_FILENAME_LENGTH+1];
- strncpy(generatedName, indexName, DB2I_INDEX_NAME_LENGTH_TO_PRESERVE);
- generatedName[DB2I_INDEX_NAME_LENGTH_TO_PRESERVE] = 0;
- char* endOfGeneratedName;
-
- if (type == typeDefault)
- {
- strcat(generatedName, DB2I_DEFAULT_INDEX_NAME_DELIMITER);
- endOfGeneratedName = strend(generatedName);
- }
- else if (type != typeNone)
- {
- strcat(generatedName, DB2I_ADDL_INDEX_NAME_DELIMITER);
- endOfGeneratedName = strend(generatedName);
- *(endOfGeneratedName-2) = char(type);
- }
-
- uint lenWithoutFile = endOfGeneratedName - generatedName;
-
- char strippedTableName[MAX_DB2_FILENAME_LENGTH+1];
- if (format == ASCII_SQL)
- {
- strcpy(strippedTableName, tableName);
- stripExtraQuotes(strippedTableName+1, sizeof(strippedTableName));
- tableName = strippedTableName;
- }
-
- if (strlen(tableName) > (MAX_DB2_FILENAME_LENGTH-lenWithoutFile))
- return -1;
-
- strncat(generatedName,
- tableName+1,
- min(strlen(tableName), (MAX_DB2_FILENAME_LENGTH-lenWithoutFile))-2 );
-
- char finalName[MAX_DB2_FILENAME_LENGTH+1];
- convertMySQLNameToDB2Name(generatedName, finalName, sizeof(finalName), true, (format==ASCII_SQL));
- to.append(finalName);
-
- return 0;
-}
-
-
-void db2i_table::findConversionDefinition(enum_conversionDirection direction, uint16 fieldID)
-{
- getConversion(direction,
- mysqlTable->field[fieldID]->charset(),
- db2Field(fieldID).getCCSID(),
- conversionDefinitions[direction][fieldID]);
-}
-
-
-db2i_file::db2i_file(db2i_table* table) : db2Table(table)
-{
- commonCtorInit();
-
- DBUG_ASSERT(table->getMySQLTable()->table_name.length <= MAX_DB2_FILENAME_LENGTH-2);
-
- db2FileName = (char*)table->getDB2TableName(db2i_table::EBCDIC_NATIVE);
-}
-
-db2i_file::db2i_file(db2i_table* table, int index) : db2Table(table)
-{
- commonCtorInit();
-
- if ((index == table->getMySQLTable()->primary_key) && !table->isTemporary())
- {
- db2FileName = (char*)table->getDB2TableName(db2i_table::EBCDIC_NATIVE);
- }
- else
- {
- // Generate the index name (in index___table form); quote and EBCDICize it.
- String qualifiedPath;
- qualifiedPath.length(0);
-
- const char* asciiFileName = table->getDB2TableName(db2i_table::ASCII_NATIVE);
-
- db2i_table::appendQualifiedIndexFileName(table->getMySQLTable()->key_info[index].name,
- asciiFileName,
- qualifiedPath,
- db2i_table::ASCII_NATIVE,
- typeDefault);
-
- db2FileName = (char*)my_malloc(qualifiedPath.length()+1, MYF(MY_WME | MY_ZEROFILL));
- convToEbcdic(qualifiedPath.ptr(), db2FileName, qualifiedPath.length());
- }
-}
-
-void db2i_file::commonCtorInit()
-{
- masterDefn = 0;
- memset(&formats, 0, maxRowFormats*sizeof(RowFormat));
-}
-
-
-void db2i_file::fillILEDefn(ShrDef* defn, bool readInArrivalSeq)
-{
- defn->ObjNamLen = strlen(db2FileName);
- DBUG_ASSERT(defn->ObjNamLen <= sizeof(defn->ObjNam));
- memcpy(defn->ObjNam, db2FileName, defn->ObjNamLen);
- defn->ArrSeq[0] = (readInArrivalSeq ? QMY_YES : QMY_NO);
-}
-
diff --git a/storage/ibmdb2i/db2i_file.h b/storage/ibmdb2i/db2i_file.h
deleted file mode 100644
index 7b63b18c315..00000000000
--- a/storage/ibmdb2i/db2i_file.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_FILE_H
-#define DB2I_FILE_H
-
-#include "db2i_global.h"
-#include "db2i_ileBridge.h"
-#include "db2i_validatedPointer.h"
-#include "db2i_iconv.h"
-#include "db2i_charsetSupport.h"
-
-const char FID_EXT[] = ".FID";
-
-class db2i_file;
-
-#pragma pack(1)
-struct DB2LobField
-{
- char reserved1;
- uint32 length;
- char reserved2[4];
- uint32 ordinal;
- ILEMemHandle dataHandle;
- char reserved3[8];
-};
-#pragma pack(pop)
-
-class DB2Field
-{
- public:
- uint16 getType() const { return *(uint16*)(&definition.ColType); }
- uint16 getByteLengthInRecord() const { return definition.ColLen; }
- uint16 getDataLengthInRecord() const
- {
- return (getType() == QMY_VARCHAR || getType() == QMY_VARGRAPHIC ? definition.ColLen - 2 : definition.ColLen);
- }
- uint16 getCCSID() const { return *(uint16*)(&definition.ColCCSID); }
- bool isBlob() const
- {
- uint16 type = getType();
- return (type == QMY_BLOBCLOB || type == QMY_DBCLOB);
- }
- uint16 getBufferOffset() const { return definition.ColBufOff; }
- uint16 calcBlobPad() const
- {
- DBUG_ASSERT(isBlob());
- return getByteLengthInRecord() - sizeof (DB2LobField);
- }
- DB2LobField* asBlobField(char* buf) const
- {
- DBUG_ASSERT(isBlob());
- return (DB2LobField*)(buf + getBufferOffset() + calcBlobPad());
- }
- private:
- col_def_t definition;
-};
-
-
-/**
- @class db2i_table
-
- @details
- This class describes the logical SQL table provided by DB2.
- It stores "table-scoped" information such as the name of the
- DB2 schema, BLOB descriptions, and the corresponding MySQL table definition.
- Only one instance exists per SQL table.
-*/
-class db2i_table
-{
- public:
- enum NameFormatFlags
- {
- ASCII_SQL,
- ASCII_NATIVE,
- EBCDIC_NATIVE
- };
-
- db2i_table(const TABLE_SHARE* myTable, const char* path = NULL);
-
- ~db2i_table();
-
- int32 initDB2Objects(const char* path);
-
- const TABLE_SHARE* getMySQLTable() const
- {
- return mysqlTable;
- }
-
- uint64 getStartId() const
- {
- return db2StartId;
- }
-
- void updateStartId(uint64 newStartId)
- {
- db2StartId = newStartId;
- }
-
- bool hasBlobs() const
- {
- return (blobFieldCount > 0);
- }
-
- uint16 getBlobCount() const
- {
- return blobFieldCount;
- }
-
- uint getBlobFieldActualSize(uint fieldIndex) const
- {
- return blobFieldActualSizes[getBlobIdFromField(fieldIndex)];
- }
-
- void updateBlobFieldActualSize(uint fieldIndex, uint32 newSize)
- {
- // It's OK that this isn't threadsafe, since this is just an advisory
- // value. If a race condition causes the lesser of two values to be stored,
- // that's OK.
- uint16 blobID = getBlobIdFromField(fieldIndex);
- DBUG_ASSERT(blobID < blobFieldCount);
-
- if (blobFieldActualSizes[blobID] < newSize)
- {
- blobFieldActualSizes[blobID] = newSize;
- }
- }
-
-
-
- const char* getDB2LibName(NameFormatFlags format = EBCDIC_NATIVE)
- {
- switch (format)
- {
- case EBCDIC_NATIVE:
- return db2LibNameEbcdic; break;
- case ASCII_NATIVE:
- return db2LibNameAscii; break;
- case ASCII_SQL:
- return db2LibNameSQLAscii; break;
- default:
- DBUG_ASSERT(0);
- }
- return NULL;
- }
-
- const char* getDB2TableName(NameFormatFlags format = EBCDIC_NATIVE) const
- {
- switch (format)
- {
- case EBCDIC_NATIVE:
- return db2TableNameEbcdic; break;
- case ASCII_NATIVE:
- return db2TableNameAscii; break;
- case ASCII_SQL:
- return db2TableNameAscii; break;
- break;
- default:
- DBUG_ASSERT(0);
- }
- return NULL;
- }
-
- DB2Field& db2Field(int fieldID) const { return db2Fields[fieldID]; }
- DB2Field& db2Field(const Field* field) const { return db2Field(field->field_index); }
-
- void processFormatSpace();
-
- void* getFormatSpace(size_t& spaceNeeded)
- {
- DBUG_ASSERT(formatSpace == NULL);
- spaceNeeded = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field);
- formatSpace.alloc(spaceNeeded);
- return (void*)formatSpace;
- }
-
- bool isTemporary() const
- {
- return isTemporaryTable;
- }
-
- void getDB2QualifiedName(char* to);
- static void getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format=ASCII_SQL);
- static void getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format=ASCII_SQL);
- static void getDB2QualifiedNameFromPath(const char* path, char* to);
- static int32 appendQualifiedIndexFileName(const char* indexName,
- const char* tableName,
- String& to,
- NameFormatFlags format=ASCII_SQL,
- enum_DB2I_INDEX_TYPE type=typeDefault);
-
- uint16 getBlobIdFromField(uint16 fieldID) const
- {
- for (int i = 0; i < blobFieldCount; ++i)
- {
- if (blobFields[i] == fieldID)
- return i;
- }
- DBUG_ASSERT(0);
- return 0;
- }
-
- iconv_t& getConversionDefinition(enum_conversionDirection direction,
- uint16 fieldID)
- {
- if (conversionDefinitions[direction][fieldID] == (iconv_t)(-1))
- findConversionDefinition(direction, fieldID);
-
- return conversionDefinitions[direction][fieldID];
- }
-
- const db2i_file* dataFile() const
- {
- return physicalFile;
- }
-
- const db2i_file* indexFile(uint idx) const
- {
- return logicalFiles[idx];
- }
-
- const char* getFileLevelID() const
- {
- return fileLevelID;
- }
-
- static void deleteAssocFiles(const char* name);
- static void renameAssocFiles(const char* from, const char* to);
-
- int fastInitForCreate(const char* path);
- int initDiscoveredTable(const char* path);
-
- uint16* blobFields;
-
-private:
-
- void findConversionDefinition(enum_conversionDirection direction, uint16 fieldID);
- static void filenameToTablename(const char* in, char* out, size_t outlen);
- static size_t smartFilenameToTableName(const char *in, char* out, size_t outlen);
- void convertNativeToSQLName(const char* input,
- char* output)
- {
-
- output[0] = input[0];
-
- uint o = 1;
- uint i = 1;
- do
- {
- output[o++] = input[i];
- if (input[i] == '"' && input[i+1])
- output[o++] = '"';
- } while (input[++i]);
-
- output[o] = 0; // This isn't the most user-friendly way to handle overflows,
- // but at least its safe.
- }
-
- bool doFileIDsMatch(const char* path);
-
- ValidatedPointer<format_hdr_t> formatSpace;
- DB2Field* db2Fields;
- uint64 db2StartId; // Starting value for identity column
- uint16 blobFieldCount; // Count of LOB fields in the DB2 table
- uint* blobFieldActualSizes; // Array of LOB field lengths (actual vs. allocated).
- // This is updated as LOBs are read and will contain
- // the length of the longest known LOB in that field.
- iconv_t* conversionDefinitions[2];
-
- const TABLE_SHARE* mysqlTable;
- uint16 logicalFileCount;
- char* db2LibNameEbcdic; // Quoted and in EBCDIC
- char* db2LibNameAscii;
- char* db2TableNameEbcdic;
- char* db2TableNameAscii;
- char* db2TableNameSQLAscii;
- char* db2LibNameSQLAscii;
-
- db2i_file* physicalFile;
- db2i_file** logicalFiles;
-
- bool isTemporaryTable;
- char fileLevelID[13];
-};
-
-/**
- @class db2i_file
-
- @details This class describes a file object underlaying a particular SQL
- table. Both "physical files" (data) and "logical files" (indices) are
- described by this class. Only one instance of the class exists per DB2 file
- object. The single instance is responsible for de/allocating the multiple
- handles used by the handlers.
-*/
-class db2i_file
-{
-
-public:
- struct RowFormat
- {
- uint16 readRowLen;
- uint16 readRowNullOffset;
- uint16 writeRowLen;
- uint16 writeRowNullOffset;
- char inited;
- };
-
-public:
-
- // Construct an instance for a physical file.
- db2i_file(db2i_table* table);
-
- // Construct an instance for a logical file.
- db2i_file(db2i_table* table, int index);
-
- ~db2i_file()
- {
- if (masterDefn)
- db2i_ileBridge::getBridgeForThread()->deallocateFile(masterDefn);
-
- if (db2FileName != (char*)db2Table->getDB2TableName(db2i_table::EBCDIC_NATIVE))
- my_free(db2FileName, MYF(0));
- }
-
- // This is roughly equivalent to an "open". It tells ILE to allocate a descriptor
- // for the file. The associated handle is returned to the caller.
- int allocateNewInstance(FILE_HANDLE* newHandle, ILEMemHandle inuseSpace) const
- {
- int rc;
-
- rc = db2i_ileBridge::getBridgeForThread()->allocateFileInstance(masterDefn,
- inuseSpace,
- newHandle);
-
- if (rc) *newHandle = 0;
-
- return rc;
- }
-
- // This obtains the row layout associated with a particular access intent for
- // an open instance of the file.
- int obtainRowFormat(FILE_HANDLE instanceHandle,
- char intent,
- char commitLevel,
- const RowFormat** activeFormat) const
- {
- DBUG_ENTER("db2i_file::obtainRowFormat");
- RowFormat* rowFormat;
-
- if (intent == QMY_UPDATABLE)
- rowFormat = &(formats[readWrite]);
- else if (intent == QMY_READ_ONLY)
- rowFormat = &(formats[readOnly]);
-
- if (unlikely(!rowFormat->inited))
- {
- int rc = db2i_ileBridge::getBridgeForThread()->
- initFileForIO(instanceHandle,
- intent,
- commitLevel,
- &(rowFormat->writeRowLen),
- &(rowFormat->writeRowNullOffset),
- &(rowFormat->readRowLen),
- &(rowFormat->readRowNullOffset));
- if (rc) DBUG_RETURN(rc);
- rowFormat->inited = 1;
- }
-
- *activeFormat = rowFormat;
- DBUG_RETURN(0);
- }
-
- const char* getDB2FileName() const
- {
- return db2FileName;
- }
-
- void fillILEDefn(ShrDef* defn, bool readInArrivalSeq);
-
- void setMasterDefnHandle(FILE_HANDLE handle)
- {
- masterDefn = handle;
- }
-
- FILE_HANDLE getMasterDefnHandle() const
- {
- return masterDefn;
- }
-
-private:
- enum RowFormats
- {
- readOnly = 0,
- readWrite,
- maxRowFormats
- };
-
- mutable RowFormat formats[maxRowFormats];
-
- void commonCtorInit();
-
- char* db2FileName; // Quoted and in EBCDIC
-
- db2i_table* db2Table; // The logical SQL table contained by this file.
-
- bool db2CanSort;
-
- FILE_HANDLE masterDefn;
-};
-
-
-#endif
diff --git a/storage/ibmdb2i/db2i_global.h b/storage/ibmdb2i/db2i_global.h
deleted file mode 100644
index d201fbd8124..00000000000
--- a/storage/ibmdb2i/db2i_global.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_GLOBAL_H
-#define DB2I_GLOBAL_H
-
-#define MYSQL_SERVER 1
-
-#include "my_global.h"
-#include "my_sys.h"
-
-const uint MAX_DB2_KEY_PARTS=120;
-const int MAX_DB2_V5R4_LIBNAME_LENGTH = 10;
-const int MAX_DB2_V6R1_LIBNAME_LENGTH = 30;
-const int MAX_DB2_SCHEMANAME_LENGTH=258;
-const int MAX_DB2_FILENAME_LENGTH=258;
-const int MAX_DB2_COLNAME_LENGTH=128;
-const int MAX_DB2_SAVEPOINTNAME_LENGTH=128;
-const int MAX_DB2_QUALIFIEDNAME_LENGTH=MAX_DB2_V6R1_LIBNAME_LENGTH + 1 + MAX_DB2_FILENAME_LENGTH;
-const uint32 MAX_CHAR_LENGTH = 32765;
-const uint32 MAX_VARCHAR_LENGTH = 32739;
-const uint32 MAX_DEC_PRECISION = 63;
-const uint32 MAX_BLOB_LENGTH = 2147483646;
-const uint32 MAX_BINARY_LENGTH = MAX_CHAR_LENGTH;
-const uint32 MAX_VARBINARY_LENGTH = MAX_VARCHAR_LENGTH;
-const uint32 MAX_FULL_ALLOCATE_BLOB_LENGTH = 65536;
-const uint32 MAX_FOREIGN_LEN = 64000;
-const char* DB2I_TEMP_TABLE_SCHEMA = "QTEMP";
-const char DB2I_ADDL_INDEX_NAME_DELIMITER[5] = {'_','_','_','_','_'};
-const char DB2I_DEFAULT_INDEX_NAME_DELIMITER[3] = {'_','_','_'};
-const int DB2I_INDEX_NAME_LENGTH_TO_PRESERVE = 110;
-
-enum enum_DB2I_INDEX_TYPE
-{
- typeNone = 0,
- typeDefault = 'D',
- typeHex = 'H',
- typeAscii = 'A'
-};
-
-void* roundToQuadWordBdy(void* ptr)
-{
- return (void*)(((uint64)(ptr)+0xf) & ~0xf);
-}
-
-typedef uint64_t ILEMemHandle;
-
-struct OSVersion
-{
- uint8 v;
- uint8 r;
-};
-extern OSVersion osVersion;
-
-
-/**
- Allocate 16-byte aligned space using the MySQL heap allocator
-
- @details Many of the spaces used by the QMY_* APIS are required to be
- aligned on 16 byte boundaries. The standard system malloc will do this
- alignment by default. However, in order to use the heap debug and tracking
- features of the mysql allocator, we chose to implement an aligning wrapper
- around my_malloc. Essentially, we overallocate the storage space, find the
- first aligned address in the space, store a pointer to the true malloc
- allocation in the bytes immediately preceding the aligned address, and return
- the aligned address to the caller.
-
- @parm size The size of heap storage needed
-
- @return A 16-byte aligned pointer to the storage requested.
-*/
-void* malloc_aligned(size_t size)
-{
- char* p;
- char* base;
- base = (char*)my_malloc(size + sizeof(void*) + 15, MYF(MY_WME));
- if (likely(base))
- {
- p = (char*)roundToQuadWordBdy(base + sizeof(void*));
- char** p2 = (char**)(p - sizeof(void*));
- *p2 = base;
- }
- else
- p = NULL;
-
- return p;
-}
-
-/**
- Free a 16-byte aligned space alloced by malloc_aligned
-
- @details We know that a pointer to the true malloced storage immediately
- precedes the aligned address, so we pull that out and call my_free().
-
- @parm p A 16-byte aligned pointer generated by malloc_aligned
-*/
-void free_aligned(void* p)
-{
- if (likely(p))
- {
- my_free(*(char**)((char*)p-sizeof(void*)), MYF(0));
- }
-}
-
-#endif
diff --git a/storage/ibmdb2i/db2i_iconv.h b/storage/ibmdb2i/db2i_iconv.h
deleted file mode 100644
index 9fc6e4ed636..00000000000
--- a/storage/ibmdb2i/db2i_iconv.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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.
-*/
-
-/**
- @file
-
- @brief Used to redefine iconv symbols to the optimized "myconv" ones
-*/
-
-#ifndef DB2I_ICONV_H
-#define DB2I_ICONV_H
-
-#include "db2i_myconv.h"
-#define iconv_open(A, B) myconv_open(A, B, CONVERTER_DMAP)
-#define iconv_close myconv_close
-#define iconv myconv_dmap
-#define iconv_t myconv_t
-
-#endif
diff --git a/storage/ibmdb2i/db2i_ileBridge.cc b/storage/ibmdb2i/db2i_ileBridge.cc
deleted file mode 100644
index 68ae2c2bb72..00000000000
--- a/storage/ibmdb2i/db2i_ileBridge.cc
+++ /dev/null
@@ -1,1342 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_ileBridge.h"
-#include "my_dbug.h"
-#include "db2i_global.h"
-#include "db2i_charsetSupport.h"
-#include "db2i_errors.h"
-
-
-// static class member data
-ILEpointer* db2i_ileBridge::functionSymbols;
-db2i_ileBridge* db2i_ileBridge::globalBridge;
-#ifndef DBUG_OFF
-uint32 db2i_ileBridge::registeredPtrs;
-#endif
-
-pthread_key(IleParms*, THR_ILEPARMS);
-
-static void ileParmsDtor(void* parmsToFree)
-{
- if (parmsToFree)
- {
- free_aligned(parmsToFree);
- DBUG_PRINT("db2i_ileBridge", ("Freeing space for parms"));
- }
-}
-
-
-/**
- Convert a timestamp in ILE time format into a unix time_t
-*/
-static inline time_t convertILEtime(const ILE_time_t& input)
-{
- tm temp;
-
- temp.tm_sec = input.Second;
- temp.tm_min = input.Minute;
- temp.tm_hour = input.Hour;
- temp.tm_mday = input.Day;
- temp.tm_mon = input.Month-1;
- temp.tm_year = input.Year - 1900;
- temp.tm_isdst = -1;
-
- return mktime(&temp);
-}
-
-/**
- Allocate and intialize a new bridge structure
-*/
-db2i_ileBridge* db2i_ileBridge::createNewBridge(CONNECTION_HANDLE connID)
-{
- DBUG_PRINT("db2i_ileBridge::createNewBridge",("Building new bridge..."));
- db2i_ileBridge* newBridge = (db2i_ileBridge*)my_malloc(sizeof(db2i_ileBridge), MYF(MY_WME));
-
- if (unlikely(newBridge == NULL))
- return NULL;
-
- newBridge->stmtTxActive = false;
- newBridge->connErrText = NULL;
- newBridge->pendingLockedHandles.head = NULL;
- newBridge->cachedConnectionID = connID;
-
- return newBridge;
-}
-
-
-void db2i_ileBridge::destroyBridge(db2i_ileBridge* bridge)
-{
- bridge->freeErrorStorage();
- my_free(bridge, MYF(0));
-}
-
-
-void db2i_ileBridge::destroyBridgeForThread(const THD* thd)
-{
- void* thdData = *thd_ha_data(thd, ibmdb2i_hton);
- if (thdData != NULL)
- {
- destroyBridge((db2i_ileBridge*)thdData);
- }
-}
-
-
-void db2i_ileBridge::registerPtr(const void* ptr, ILEMemHandle* receiver)
-{
- static const arg_type_t ileSignature[] = { ARG_MEMPTR, ARG_END };
-
- if (unlikely(ptr == NULL))
- {
- *receiver = 0;
- return;
- }
-
- struct ArgList
- {
- ILEarglist_base base;
- ILEpointer ptr;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->ptr.s.addr = (address64_t)(ptr);
-
- _ILECALL(&functionSymbols[funcRegisterSpace],
- &arguments->base,
- ileSignature,
- RESULT_INT64);
-
-#ifndef DBUG_OFF
- uint32 truncHandle = arguments->base.result.r_uint64;
- DBUG_PRINT("db2i_ileBridge::registerPtr",("Register 0x%p with handle %d", ptr, truncHandle));
- getBridgeForThread()->registeredPtrs++;
-#endif
-
- *receiver = arguments->base.result.r_uint64;
- return;
-}
-
-void db2i_ileBridge::unregisterPtr(ILEMemHandle handle)
-{
- static const arg_type_t ileSignature[] = { ARG_UINT64, ARG_END };
-
- if (unlikely(handle == NULL))
- return;
-
- struct ArgList
- {
- ILEarglist_base base;
- uint64 handle;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->handle = (uint64)(handle);
-
- _ILECALL(&functionSymbols[funcUnregisterSpace],
- &arguments->base,
- ileSignature,
- RESULT_VOID);
-
-#ifndef DBUG_OFF
- DBUG_PRINT("db2i_ileBridge::unregisterPtr",("Unregister handle %d", (uint32)handle));
- getBridgeForThread()->registeredPtrs--;
-#endif
-}
-
-
-
-/**
- Initialize the bridge component
-
- @details Resolves srvpgm and function names of the APIs. If this fails,
- the approrpiate operating system support (PTFs) is probably not installed.
-
- WARNING:
- Must be called before any other functions in this class are used!!!!
- Can only be called by a single thread!
-*/
-int db2i_ileBridge::setup()
-{
- static const char funcNames[db2i_ileBridge::funcListEnd][32] =
- {
- {"QmyRegisterParameterSpaces"},
- {"QmyRegisterSpace"},
- {"QmyUnregisterSpace"},
- {"QmyProcessRequest"}
- };
-
- DBUG_ENTER("db2i_ileBridge::setup");
-
- int actmark = _ILELOAD("QSYS/QMYSE", ILELOAD_LIBOBJ);
- if ( actmark == -1 )
- {
- DBUG_PRINT("db2i_ileBridge::setup", ("srvpgm activation failed"));
- DBUG_RETURN(1);
- }
-
- functionSymbols = (ILEpointer*)malloc_aligned(sizeof(ILEpointer) * db2i_ileBridge::funcListEnd);
-
- for (int i = 0; i < db2i_ileBridge::funcListEnd; i++)
- {
- if (_ILESYM(&functionSymbols[i], actmark, funcNames[i]) == -1)
- {
- DBUG_PRINT("db2i_ileBridge::setup",
- ("resolve of %s failed", funcNames[i]));
- DBUG_RETURN(errno);
- }
- }
-
- pthread_key_create(&THR_ILEPARMS, &ileParmsDtor);
-
-#ifndef DBUG_OFF
- registeredPtrs = 0;
-#endif
-
- globalBridge = createNewBridge(0);
-
- DBUG_RETURN(0);
-}
-
-/**
- Cleanup any resources before shutting down plug-in
-*/
-void db2i_ileBridge::takedown()
-{
- if (globalBridge)
- destroyBridge(globalBridge);
- free_aligned(functionSymbols);
-}
-
-/**
- Call off to QmyProcessRequest to perform the API that the caller prepared
-*/
-inline int32 db2i_ileBridge::doIt()
-{
- static const arg_type_t ileSignature[] = {ARG_END};
-
- struct ArgList
- {
- ILEarglist_base base;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- _ILECALL(&functionSymbols[funcProcessRequest],
- &arguments->base,
- ileSignature,
- RESULT_INT32);
-
- return translateErrorCode(arguments->base.result.s_int32.r_int32);
-}
-
-/**
- Call off to QmyProcessRequest to perform the API that the caller prepared and
- log any errors that may occur.
-*/
-inline int32 db2i_ileBridge::doItWithLog()
-{
- int32 rc = doIt();
-
- if (unlikely(rc))
- {
- // Only report errors that we weren't expecting
- if (rc != tacitErrors[0] &&
- rc != tacitErrors[1] &&
- rc != QMY_ERR_END_OF_BLOCK)
- reportSystemAPIError(rc, (Qmy_Error_output_t*)parms()->outParms);
- }
- memset(tacitErrors, 0, sizeof(tacitErrors));
-
- return rc;
-}
-
-
-/**
- Interface to QMY_ALLOCATE_SHARE API
-
- See QMY_ALLOCATE_SHARE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::allocateFileDefn(ILEMemHandle definitionSpace,
- ILEMemHandle handleSpace,
- uint16 fileCount,
- const char* schemaName,
- uint16 schemaNameLength,
- ILEMemHandle formatSpace,
- uint32 formatSpaceLen)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MAOS0100 *input = (Qmy_MAOS0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_ALLOCATE_SHARE;
- input->ShrDefSpcHnd = definitionSpace;
- input->ShrHndSpcHnd = handleSpace;
- input->ShrDefCnt = fileCount;
- input->FmtSpcHnd = formatSpace;
- input->FmtSpcLen = formatSpaceLen;
-
- if (schemaNameLength > sizeof(input->SchNam))
- {
- // This should never happen!
- DBUG_ASSERT(0);
- return HA_ERR_GENERIC;
- }
-
- memcpy(input->SchNam, schemaName, schemaNameLength);
- input->SchNamLen = schemaNameLength;
-
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_ALLOCATE_INSTANCE API
-
- See QMY_ALLOCATE_INSTANCE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::allocateFileInstance(FILE_HANDLE defnHandle,
- ILEMemHandle inuseSpace,
- FILE_HANDLE* instance)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MAOI0100 *input = (Qmy_MAOI0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_ALLOCATE_INSTANCE;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
- input->UseSpcHnd = inuseSpace;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MAOI0100_output* output = (Qmy_MAOI0100_output*)parmBlock->outParms;
- DBUG_ASSERT(instance);
- *instance = output->ObjHnd;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_DEALLOCATE_OBJECT API
-
- See QMY_DEALLOCATE_OBJECT documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::deallocateFile(FILE_HANDLE rfileHandle,
- bool postDropTable)
-{
- IleParms* parmBlock = parms();
- Qmy_MDLC0100 *input = (Qmy_MDLC0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DEALLOCATE_OBJECT;
- input->ObjHnd = rfileHandle;
- input->ObjDrp[0] = (postDropTable ? QMY_YES : QMY_NO);
-
- DBUG_PRINT("db2i_ileBridge::deallocateFile", ("Deallocating %d", (uint32)rfileHandle));
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_OBJECT_INITIALIZATION API
-
- See QMY_OBJECT_INITIALIZATION documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::initFileForIO(FILE_HANDLE rfileHandle,
- char accessIntent,
- char commitLevel,
- uint16* inRecSize,
- uint16* inRecNullOffset,
- uint16* outRecSize,
- uint16* outRecNullOffset)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MOIX0100 *input = (Qmy_MOIX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_OBJECT_INITIALIZATION;
- input->CmtLvl[0] = commitLevel;
- input->Intent[0] = accessIntent;
- input->ObjHnd = rfileHandle;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MOIX0100_output* output = (Qmy_MOIX0100_output*)parmBlock->outParms;
- *inRecSize = output->InNxtRowOff;
- *inRecNullOffset = output->InNullMapOff;
- *outRecSize = output->OutNxtRowOff;
- *outRecNullOffset = output->OutNullMapOff;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_READ_ROWS API for reading a row with a specific RRN.
-
- See QMY_READ_ROWS documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::readByRRN(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 inRRN,
- char accessIntent,
- char commitLevel)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MRDX0100 *input = (Qmy_MRDX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_READ_ROWS;
- input->CmtLvl[0] = commitLevel;
- input->ObjHnd = rfileHandle;
- input->Intent[0] = accessIntent;
- input->OutSpcHnd = (uint64)buf;
- input->RelRowNbr = inRRN;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- rc = 0;
- DBUG_PRINT("db2i_ileBridge::readByRRN", ("End of block signalled"));
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_WRITE_ROWS API.
-
- See QMY_WRITE_ROWS documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::writeRows(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char commitLevel,
- int64* outIdVal,
- bool* outIdGen,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen,
- uint32* outIdIncrement)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MWRT0100 *input = (Qmy_MWRT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_WRITE_ROWS;
- input->CmtLvl[0] = commitLevel;
-
- input->ObjHnd = rfileHandle;
- input->InSpcHnd = (uint64_t) buf;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- Qmy_MWRT0100_output_t* output = (Qmy_MWRT0100_output_t*)parmBlock->outParms;
- if (likely(rc == 0 || rc == HA_ERR_FOUND_DUPP_KEY))
- {
- DBUG_ASSERT(dupKeyRRN && dupKeyName && dupKeyNameLen && outIdGen && outIdIncrement && outIdVal);
- *dupKeyRRN = output->DupRRN;
- *dupKeyName = (char*)parmBlock->outParms + output->DupObjNamOff;
- *dupKeyNameLen = output->DupObjNamLen;
- *outIdGen = (output->NewIdGen[0] == QMY_YES ? TRUE : FALSE);
- if (*outIdGen == TRUE)
- {
- *outIdIncrement = output->IdIncrement;
- *outIdVal = output->NewIdVal;
- }
- }
-
- return rc;
-
-}
-
-/**
- Interface to QMY_EXECUTE_IMMEDIATE API.
-
- See QMY_EXECUTE_IMMEDIATE documentation for more information about
- parameters and return codes.
-*/
-uint32 db2i_ileBridge::execSQL(const char* statement,
- uint32 statementCount,
- uint8 commitLevel,
- bool autoCreateSchema,
- bool dropSchema,
- bool noCommit,
- FILE_HANDLE fileHandle)
-
-{
- IleParms* parmBlock = parms();
- Qmy_MSEI0100 *input = (Qmy_MSEI0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_EXECUTE_IMMEDIATE;
-
- registerPtr(statement, &input->StmtsSpcHnd);
-
- input->NbrStmts = statementCount;
- *(uint16*)(&input->StmtCCSID) = 850;
- input->AutoCrtSchema[0] = (autoCreateSchema == TRUE ? QMY_YES : QMY_NO);
- input->DropSchema[0] = (dropSchema == TRUE ? QMY_YES : QMY_NO);
- input->CmtLvl[0] = commitLevel;
- if ((commitLevel == QMY_NONE && statementCount == 1) || noCommit)
- {
- input->CmtBefore[0] = QMY_NO;
- input->CmtAfter[0] = QMY_NO;
- }
- else
- {
- input->CmtBefore[0] = QMY_YES;
- input->CmtAfter[0] = QMY_YES;
- }
- input->CnnHnd = current_thd->thread_id;
- input->ObjHnd = fileHandle;
-
- int32 rc = doItWithLog();
-
- unregisterPtr(input->StmtsSpcHnd);
-
- return rc;
-}
-
-/**
- Interface to QMY_PREPARE_OPEN_CURSOR API.
-
- See QMY_PREPARE_OPEN_CURSOR documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::prepOpen(const char* statement,
- FILE_HANDLE* rfileHandle,
- uint32* recLength)
-{
- IleParms* parmBlock = parms();
- Qmy_MSPO0100 *input = (Qmy_MSPO0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_PREPARE_OPEN_CURSOR;
-
- registerPtr(statement, &input->StmtsSpcHnd );
- *(uint16*)(&input->StmtCCSID) = 850;
- input->CnnHnd = current_thd->thread_id;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MSPO0100_output* output = (Qmy_MSPO0100_output*)parmBlock->outParms;
- *rfileHandle = output->ObjHnd;
- *recLength = max(output->InNxtRowOff, output->OutNxtRowOff);
- }
-
-
- unregisterPtr(input->StmtsSpcHnd);
-
- return rc;
-}
-
-
-/**
- Interface to QMY_DELETE_ROW API.
-
- See QMY_DELETE_ROW documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::deleteRow(FILE_HANDLE rfileHandle,
- uint32 rrn)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDLT0100 *input = (Qmy_MDLT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DELETE_ROW;
- input->ObjHnd = rfileHandle;
- input->RelRowNbr = rrn;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_UPDATE_ROW API.
-
- See QMY_UPDATE_ROW documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::updateRow(FILE_HANDLE rfileHandle,
- uint32 rrn,
- ILEMemHandle buf,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MUPD0100 *input = (Qmy_MUPD0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_UPDATE_ROW;
- input->ObjHnd = rfileHandle;
- input->InSpcHnd = (uint64)buf;
- input->RelRowNbr = rrn;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (rc == HA_ERR_FOUND_DUPP_KEY)
- {
- Qmy_MUPD0100_output* output = (Qmy_MUPD0100_output*)parmBlock->outParms;
- DBUG_ASSERT(dupKeyRRN && dupKeyName && dupKeyNameLen);
- *dupKeyRRN = output->DupRRN;
- *dupKeyName = (char*)parmBlock->outParms + output->DupObjNamOff;
- *dupKeyNameLen = output->DupObjNamLen;
- }
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_RANGE API.
-
- See QMY_DESCRIBE_RANGE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::recordsInRange(FILE_HANDLE defnHandle,
- ILEMemHandle inSpc,
- uint32 inKeyCnt,
- uint32 inLiteralCnt,
- uint32 inBoundsOff,
- uint32 inLitDefOff,
- uint32 inLiteralsOff,
- uint32 inCutoff,
- uint32 inSpcLen,
- uint16 inEndByte,
- uint64* outRecCnt,
- uint16* outRtnCode)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MDRG0100 *input = (Qmy_MDRG0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_RANGE;
- input->ShrHnd = defnHandle;
- input->SpcHnd = (uint64)inSpc;
- input->KeyCnt = inKeyCnt;
- input->LiteralCnt = inLiteralCnt;
- input->BoundsOff = inBoundsOff;
- input->LitDefOff = inLitDefOff;
- input->LiteralsOff = inLiteralsOff;
- input->Cutoff = inCutoff;
- input->SpcLen = inSpcLen;
- input->EndByte = inEndByte;
- input->CnnHnd = cachedConnectionID;
-
- int rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDRG0100_output* output = (Qmy_MDRG0100_output*)parmBlock->outParms;
- DBUG_ASSERT(outRecCnt && outRtnCode);
- *outRecCnt = output->RecCnt;
- *outRtnCode = output->RtnCode;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_RELEASE_ROW API.
-
- See QMY_RELEASE_ROW documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::rrlslck(FILE_HANDLE rfileHandle, char accessIntent)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MRRX0100 *input = (Qmy_MRRX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_RELEASE_ROW;
-
- input->ObjHnd = rfileHandle;
- input->CnnHnd = cachedConnectionID;
- input->Intent[0] = accessIntent;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-/**
- Interface to QMY_LOCK_OBJECT API.
-
- See QMY_LOCK_OBJECT documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::lockObj(FILE_HANDLE defnHandle,
- uint64 lockVal,
- char lockAction,
- char lockType,
- char lockTimeout)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MOLX0100 *input = (Qmy_MOLX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_LOCK_OBJECT;
- input->ShrHnd = defnHandle;
- input->LckTimeoutVal = lockVal;
- input->Action[0] = lockAction;
- input->LckTyp[0] = lockType;
- input->LckTimeout[0] = lockTimeout;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_CONSTRAINTS API.
-
- See QMY_DESCRIBE_CONSTRAINTS documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::constraints(FILE_HANDLE defnHandle,
- ILEMemHandle inSpc,
- uint32 inSpcLen,
- uint32* outLen,
- uint32* outCnt)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDCT0100 *input = (Qmy_MDCT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_CONSTRAINTS;
- input->ShrHnd = defnHandle;
- input->CstSpcHnd = (uint64)inSpc;
- input->CstSpcLen = inSpcLen;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDCT0100_output* output = (Qmy_MDCT0100_output*)parmBlock->outParms;
- DBUG_ASSERT(outLen && outCnt);
- *outLen = output->NeededLen;
- *outCnt = output->CstCnt;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_REORGANIZE_TABLE API.
-
- See QMY_REORGANIZE_TABLE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::optimizeTable(FILE_HANDLE defnHandle)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MRGX0100 *input = (Qmy_MRGX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_REORGANIZE_TABLE;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_PROCESS_COMMITMENT_CONTROL API.
-
- See QMY_PROCESS_COMMITMENT_CONTROL documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::commitmentControl(uint8 function)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MCCX0100 *input = (Qmy_MCCX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_PROCESS_COMMITMENT_CONTROL;
- input->Function[0] = function;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_PROCESS_SAVEPOINT API.
-
- See QMY_PROCESS_SAVEPOINT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::savepoint(uint8 function,
- const char* savepointName)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- DBUG_PRINT("db2i_ileBridge::savepoint",("%d %s", (uint32)function, savepointName));
-
- IleParms* parmBlock = parms();
- Qmy_MSPX0100 *input = (Qmy_MSPX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- char* savPtNam = (char*)(input+1);
-
- input->Format = QMY_PROCESS_SAVEPOINT;
-
- if (strlen(savepointName) > MAX_DB2_SAVEPOINTNAME_LENGTH)
- {
- DBUG_ASSERT(0);
- return HA_ERR_GENERIC;
- }
- strcpy(savPtNam, savepointName);
-
- input->Function[0] = function;
- input->SavPtNamOff = savPtNam - (char*)(input);
- input->SavPtNamLen = strlen(savepointName);
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-static ILEMemHandle traceSpcHandle;
-/**
- Do initialization for the QMY_* APIs.
-
- @parm aspName The name of the relational database to use for all
- connections.
-
- @return 0 if successful; error otherwise
-*/
-int32 db2i_ileBridge::initILE(const char* aspName,
- uint16* traceCtlPtr)
-{
- // We forego the typical thread-based parms space because MySQL doesn't
- // allow us to clean it up before checking for memory leaks. As a result
- // we get a complaint about leaked memory on server shutdown.
- int32 rc;
- char inParms[db2i_ileBridge_MAX_INPARM_SIZE];
- char outParms[db2i_ileBridge_MAX_OUTPARM_SIZE];
- if (rc = registerParmSpace(inParms, outParms))
- {
- reportSystemAPIError(rc, NULL);
- return rc;
- }
-
- registerPtr(traceCtlPtr, &traceSpcHandle);
-
- struct ParmBlock
- {
- Qmy_MINI0100 parms;
- } *parmBlock = (ParmBlock*)inParms;
-
- memset(inParms, 0, sizeof(ParmBlock));
-
- parmBlock->parms.Format = QMY_INITIALIZATION;
-
- char paddedName[18];
- if (strlen(aspName) > sizeof(paddedName))
- {
- getErrTxt(DB2I_ERR_BAD_RDB_NAME);
- return DB2I_ERR_BAD_RDB_NAME;
- }
-
- memset(paddedName, ' ', sizeof(paddedName));
- memcpy(paddedName, aspName, strlen(aspName));
- convToEbcdic(paddedName, parmBlock->parms.RDBName, strlen(paddedName));
-
- parmBlock->parms.RDBNamLen = strlen(paddedName);
- parmBlock->parms.TrcSpcHnd = traceSpcHandle;
-
- rc = doIt();
-
- if (rc)
- {
- reportSystemAPIError(rc, (Qmy_Error_output_t*)outParms);
- }
-
- return rc;
-}
-
-/**
- Signal to the QMY_ APIs to perform any cleanup they need to do.
-*/
-int32 db2i_ileBridge::exitILE()
-{
- IleParms* parmBlock = parms();
- Qmy_MCLN0100 *input = (Qmy_MCLN0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_CLEANUP;
-
- int32 rc = doIt();
-
- if (rc)
- {
- reportSystemAPIError(rc, (Qmy_Error_output_t*)parmBlock->outParms);
- }
-
- unregisterPtr(traceSpcHandle);
-
- DBUG_PRINT("db2i_ileBridge::exitILE", ("Registered ptrs remaining: %d", registeredPtrs));
-#ifndef DBUG_OFF
- if (registeredPtrs != 0)
- printf("Oh no! IBMDB2I left some pointers registered. Count was %d.\n", registeredPtrs);
-#endif
-
- // This is needed to prevent SAFE_MALLOC from complaining at process termination.
- my_pthread_setspecific_ptr(THR_ILEPARMS, NULL);
- free_aligned(parmBlock);
-
- return rc;
-
-}
-
-
-/**
- Designate the specified addresses as parameter passing buffers.
-
- @parm in Input to the API will go here; format is defined by the individual API
- @parm out Output from the API will be; format is defined by the individual API
-
- @return 0 if success; error otherwise
-*/
-int db2i_ileBridge::registerParmSpace(char* in, char* out)
-{
- static const arg_type_t ileSignature[] = { ARG_MEMPTR, ARG_MEMPTR, ARG_END };
-
- struct ArgList
- {
- ILEarglist_base base;
- ILEpointer input;
- ILEpointer output;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->input.s.addr = (address64_t)(in);
- arguments->output.s.addr = (address64_t)(out);
-
- _ILECALL(&functionSymbols[funcRegisterParameterSpaces],
- &arguments->base,
- ileSignature,
- RESULT_INT32);
-
- return arguments->base.result.s_int32.r_int32;
-}
-
-
-/**
- Interface to QMY_OBJECT_OVERRIDE API.
-
- See QMY_OBJECT_OVERRIDE documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::objectOverride(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 recordWidth)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MOOX0100 *input = (Qmy_MOOX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_OBJECT_OVERRIDE;
- input->ObjHnd = rfileHandle;
- input->OutSpcHnd = (uint64)buf;
- input->NxtRowOff = recordWidth;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_OBJECT API for obtaining table stats.
-
- See QMY_DESCRIBE_OBJECT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::retrieveTableInfo(FILE_HANDLE defnHandle,
- uint16 dataRequested,
- ha_statistics& stats,
- ILEMemHandle inSpc)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDSO0100 *input = (Qmy_MDSO0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_OBJECT;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
-
- if (dataRequested & objLength)
- input->RtnObjLen[0] = QMY_YES;
- if (dataRequested & rowCount)
- input->RtnRowCnt[0] = QMY_YES;
- if (dataRequested & deletedRowCount)
- input->RtnDltRowCnt[0] = QMY_YES;
- if (dataRequested & rowsPerKey)
- {
- input->RowKeyHnd = (uint64)inSpc;
- input->RtnRowKey[0] = QMY_YES;
- }
- if (dataRequested & meanRowLen)
- input->RtnMeanRowLen[0] = QMY_YES;
- if (dataRequested & lastModTime)
- input->RtnModTim[0] = QMY_YES;
- if (dataRequested & createTime)
- input->RtnCrtTim[0] = QMY_YES;
- if (dataRequested & ioCount)
- input->RtnEstIoCnt[0] = QMY_YES;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDSO0100_output* output = (Qmy_MDSO0100_output*)parmBlock->outParms;
- if (dataRequested & objLength)
- stats.data_file_length = output->ObjLen;
- if (dataRequested & rowCount)
- stats.records= output->RowCnt;
- if (dataRequested & deletedRowCount)
- stats.deleted = output->DltRowCnt;
- if (dataRequested & meanRowLen)
- stats.mean_rec_length = output->MeanRowLen;
- if (dataRequested & lastModTime)
- stats.update_time = convertILEtime(output->ModTim);
- if (dataRequested & createTime)
- stats.create_time = convertILEtime(output->CrtTim);
- if (dataRequested & ioCount)
- stats.data_file_length = output->EstIoCnt;
- }
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_OBJECT API for finding index size.
-
- See QMY_DESCRIBE_OBJECT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::retrieveIndexInfo(FILE_HANDLE defnHandle,
- uint64* outPageCnt)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDSO0100 *input = (Qmy_MDSO0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_OBJECT;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
- input->RtnPageCnt[0] = QMY_YES;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDSO0100_output* output = (Qmy_MDSO0100_output*)parmBlock->outParms;
- *outPageCnt = output->PageCnt;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_CLOSE_CONNECTION API
-
- See QMY_CLOSE_CONNECTION documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::closeConnection(CONNECTION_HANDLE conn)
-{
- IleParms* parmBlock = parms();
- Qmy_MCCN0100 *input = (Qmy_MCCN0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_CLOSE_CONNECTION;
- input->CnnHnd = conn;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_INTERRUPT API
-
- See QMY_INTERRUPT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::readInterrupt(FILE_HANDLE fileHandle)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MINT0100 *input = (Qmy_MINT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_INTERRUPT;
- input->CnnHnd = cachedConnectionID;
- input->ObjHnd = fileHandle;
-
- int32 rc = doItWithLog();
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- rc = 0;
- DBUG_PRINT("db2i_ileBridge::readInterrupt", ("End of block signalled"));
- }
-
- return rc;
-}
-
-/**
- Interface to QMY_READ_ROWS API
-
- See QMY_READ_ROWS documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::read(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char accessIntent,
- char commitLevel,
- char orientation,
- bool asyncRead,
- ILEMemHandle rrn,
- ILEMemHandle key,
- uint32 keylen,
- uint16 keyParts,
- int pipeFD)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MRDX0100 *input = (Qmy_MRDX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_READ_ROWS;
- input->CmtLvl[0] = commitLevel;
-
- input->ObjHnd = rfileHandle;
- input->Intent[0] = accessIntent;
- input->OutSpcHnd = (uint64)buf;
- input->OutRRNSpcHnd = (uint64)rrn;
- input->RtnData[0] = QMY_RETURN_DATA;
-
- if (key)
- {
- input->KeySpcHnd = (uint64)key;
- input->KeyColsLen = keylen;
- input->KeyColsNbr = keyParts;
- }
-
- input->Async[0] = (asyncRead ? QMY_YES : QMY_NO);
- input->PipeDesc = pipeFD;
- input->Orientation[0] = orientation;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- // QMY_ERR_END_OF_BLOCK is informational only, so we ignore it.
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- rc = 0;
- DBUG_PRINT("db2i_ileBridge::read", ("End of block signalled"));
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_QUIESCE_OBJECT API
-
- See QMY_QUIESCE_OBJECT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::quiesceFileInstance(FILE_HANDLE rfileHandle)
-{
- IleParms* parmBlock = parms();
- Qmy_MQSC0100 *input = (Qmy_MQSC0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_QUIESCE_OBJECT;
- input->ObjHnd = rfileHandle;
-
- int32 rc = doItWithLog();
-
-#ifndef DBUG_OFF
- if (unlikely(rc))
- {
- DBUG_ASSERT(0);
- }
-#endif
-
- return rc;
-}
-
-void db2i_ileBridge::PreservedHandleList::add(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share)
-{
- NameHandlePair *newPair = (NameHandlePair*)my_malloc(sizeof(NameHandlePair), MYF(MY_WME));
-
- newPair->next = head;
- head = newPair;
-
- strcpy(newPair->name, newname);
- newPair->handle = newhandle;
- newPair->share = share;
- DBUG_PRINT("db2i_ileBridge", ("Added handle %d for %s", uint32(newhandle), newname));
-}
-
-
-FILE_HANDLE db2i_ileBridge::PreservedHandleList::findAndRemove(const char* fileName, IBMDB2I_SHARE** share)
-{
- NameHandlePair* current = head;
- NameHandlePair* prev = NULL;
-
- while (current)
- {
- NameHandlePair* next = current->next;
- if (strcmp(fileName, current->name) == 0)
- {
- FILE_HANDLE tmp = current->handle;
- *share = current->share;
- if (prev)
- prev->next = next;
- if (current == head)
- head = next;
- my_free(current, MYF(0));
- DBUG_PRINT("db2i_ileBridge", ("Found handle %d for %s", uint32(tmp), fileName));
- return tmp;
- }
- prev = current;
- current = next;
- }
-
- return 0;
-}
-
-
-IleParms* db2i_ileBridge::initParmsForThread()
-{
-
- IleParms* p = (IleParms*)malloc_aligned(sizeof(IleParms));
- DBUG_ASSERT((uint64)(&(p->outParms))% 16 == 0); // Guarantee that outParms are aligned correctly
-
- if (likely(p))
- {
- int32 rc = registerParmSpace((p->inParms), (p->outParms));
- if (likely(rc == 0))
- {
- my_pthread_setspecific_ptr(THR_ILEPARMS, p);
- DBUG_PRINT("db2i_ileBridge", ("Inited space for parms"));
- return p;
- }
- else
- reportSystemAPIError(rc, NULL);
- }
-
- return NULL;
-}
-
diff --git a/storage/ibmdb2i/db2i_ileBridge.h b/storage/ibmdb2i/db2i_ileBridge.h
deleted file mode 100644
index 10b9820d983..00000000000
--- a/storage/ibmdb2i/db2i_ileBridge.h
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_ILEBRIDGE_H
-#define DB2I_ILEBRIDGE_H
-
-#include "db2i_global.h"
-#include "mysql_priv.h"
-#include "as400_types.h"
-#include "as400_protos.h"
-#include "qmyse.h"
-#include "db2i_errors.h"
-
-typedef uint64_t FILE_HANDLE;
-typedef my_thread_id CONNECTION_HANDLE;
-const char SAVEPOINT_NAME[] = {0xD4,0xE2,0xD7,0xC9,0xD5,0xE3,0xC5,0xD9,0xD5,0x0};
-const uint32 TACIT_ERRORS_SIZE=2;
-
-enum db2i_InfoRequestSpec
-{
- objLength = 1,
- rowCount = 2,
- deletedRowCount = 4,
- rowsPerKey = 8,
- meanRowLen = 16,
- lastModTime = 32,
- createTime = 64,
- ioCount = 128
-};
-
-extern handlerton *ibmdb2i_hton;
-struct IBMDB2I_SHARE;
-
-const uint32 db2i_ileBridge_MAX_INPARM_SIZE = 512;
-const uint32 db2i_ileBridge_MAX_OUTPARM_SIZE = 512;
-
-extern pthread_key(IleParms*, THR_ILEPARMS);
-struct IleParms
-{
- char inParms[db2i_ileBridge_MAX_INPARM_SIZE];
- char outParms[db2i_ileBridge_MAX_OUTPARM_SIZE];
-};
-
-/**
- @class db2i_ileBridge
-
- Implements a connection-based interface to the QMY_* APIs
-
- @details Each client connection that touches an IBMDB2I table has a "bridge"
- associated with it. This bridge is constructed on first use and provides a
- more C-like interface to the APIs. As well, it is reponsible for tracking
- connection scoped information such as statement transaction state and error
- message text. The bridge is destroyed when the connection ends.
-*/
-class db2i_ileBridge
-{
- enum ileFuncs
- {
- funcRegisterParameterSpaces,
- funcRegisterSpace,
- funcUnregisterSpace,
- funcProcessRequest,
- funcListEnd
- };
-
- static db2i_ileBridge* globalBridge;
-public:
-
-
- static int setup();
- static void takedown();
-
- /**
- Obtain a pointer to the bridge for the current connection.
-
- If a MySQL client connection is on the stack, we get the associated brideg.
- Otherwise, we use the globalBridge.
- */
- static db2i_ileBridge* getBridgeForThread()
- {
- THD* thd = current_thd;
- if (likely(thd))
- return getBridgeForThread(thd);
-
- return globalBridge;
- }
-
- /**
- Obtain a pointer to the bridge for the specified connection.
-
- If a bridge exists already, we return it immediately. Otherwise, prepare
- a new bridge for the connection.
- */
- static db2i_ileBridge* getBridgeForThread(const THD* thd)
- {
- void* thdData = *thd_ha_data(thd, ibmdb2i_hton);
- if (likely(thdData != NULL))
- return (db2i_ileBridge*)(thdData);
-
- db2i_ileBridge* newBridge = createNewBridge(thd->thread_id);
- *thd_ha_data(thd, ibmdb2i_hton) = (void*)newBridge;
- return newBridge;
- }
-
- static void destroyBridgeForThread(const THD* thd);
- static void registerPtr(const void* ptr, ILEMemHandle* receiver);
- static void unregisterPtr(ILEMemHandle handle);
- int32 allocateFileDefn(ILEMemHandle definitionSpace,
- ILEMemHandle handleSpace,
- uint16 fileCount,
- const char* schemaName,
- uint16 schemaNameLength,
- ILEMemHandle formatSpace,
- uint32 formatSpaceLen);
- int32 allocateFileInstance(FILE_HANDLE defnHandle,
- ILEMemHandle inuseSpace,
- FILE_HANDLE* instance);
- int32 deallocateFile(FILE_HANDLE fileHandle,
- bool postDropTable=FALSE);
- int32 read(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char accessIntent,
- char commitLevel,
- char orientation,
- bool asyncRead = FALSE,
- ILEMemHandle rrn = 0,
- ILEMemHandle key = 0,
- uint32 keylen = 0,
- uint16 keyParts = 0,
- int pipeFD = -1);
- int32 readByRRN(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 inRRN,
- char accessIntent,
- char commitLevel);
- int32 writeRows(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char commitLevel,
- int64* outIdVal,
- bool* outIdGen,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen,
- uint32* outIdIncrement);
- uint32 execSQL(const char* statement,
- uint32 statementCount,
- uint8 commitLevel,
- bool autoCreateSchema = FALSE,
- bool dropSchema = FALSE,
- bool noCommit = FALSE,
- FILE_HANDLE fileHandle = 0);
- int32 prepOpen(const char* statement,
- FILE_HANDLE* rfileHandle,
- uint32* recLength);
- int32 deleteRow(FILE_HANDLE rfileHandle,
- uint32 rrn);
- int32 updateRow(FILE_HANDLE rfileHandle,
- uint32 rrn,
- ILEMemHandle buf,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen);
- int32 commitmentControl(uint8 function);
- int32 savepoint(uint8 function,
- const char* savepointName);
- int32 recordsInRange(FILE_HANDLE rfileHandle,
- ILEMemHandle inSpc,
- uint32 inKeyCnt,
- uint32 inLiteralCnt,
- uint32 inBoundsOff,
- uint32 inLitDefOff,
- uint32 inLiteralsOff,
- uint32 inCutoff,
- uint32 inSpcLen,
- uint16 inEndByte,
- uint64* outRecCnt,
- uint16* outRtnCode);
- int32 rrlslck(FILE_HANDLE rfileHandle,
- char accessIntent);
- int32 lockObj(FILE_HANDLE rfileHandle,
- uint64 inTimeoutVal,
- char inAction,
- char inLockType,
- char inTimeout);
- int32 constraints(FILE_HANDLE rfileHandle,
- ILEMemHandle inSpc,
- uint32 inSpcLen,
- uint32* outLen,
- uint32* outCnt);
- int32 optimizeTable(FILE_HANDLE rfileHandle);
- static int32 initILE(const char* aspName,
- uint16* traceCtlPtr);
- int32 initFileForIO(FILE_HANDLE rfileHandle,
- char accessIntent,
- char commitLevel,
- uint16* inRecSize,
- uint16* inRecNullOffset,
- uint16* outRecSize,
- uint16* outRecNullOffset);
- int32 readInterrupt(FILE_HANDLE fileHandle);
- static int32 exitILE();
-
- int32 objectOverride(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 recordWidth = 0);
-
- int32 retrieveTableInfo(FILE_HANDLE rfileHandle,
- uint16 dataRequested,
- ha_statistics& stats,
- ILEMemHandle inSpc = NULL);
-
- int32 retrieveIndexInfo(FILE_HANDLE rfileHandle,
- uint64* outPageCnt);
-
- int32 closeConnection(CONNECTION_HANDLE conn);
- int32 quiesceFileInstance(FILE_HANDLE rfileHandle);
-
- /**
- Mark the beginning of a "statement transaction"
-
- @detail MySQL "statement transactions" (see sql/handler.cc) are implemented
- as DB2 savepoints having a predefined name.
-
- @return 0 if successful; error otherwise
- */
- uint32 beginStmtTx()
- {
- DBUG_ENTER("db2i_ileBridge::beginStmtTx");
- if (stmtTxActive)
- DBUG_RETURN(0);
-
- stmtTxActive = true;
-
- DBUG_RETURN(savepoint(QMY_SET_SAVEPOINT, SAVEPOINT_NAME));
- }
-
- /**
- Commit a "statement transaction"
-
- @return 0 if successful; error otherwise
- */
- uint32 commitStmtTx()
- {
- DBUG_ENTER("db2i_ileBridge::commitStmtTx");
- DBUG_ASSERT(stmtTxActive);
- stmtTxActive = false;
- DBUG_RETURN(savepoint(QMY_RELEASE_SAVEPOINT, SAVEPOINT_NAME));
- }
-
- /**
- Roll back a "statement transaction"
-
- @return 0 if successful; error otherwise
- */
- uint32 rollbackStmtTx()
- {
- DBUG_ENTER("db2i_ileBridge::rollbackStmtTx");
- DBUG_ASSERT(stmtTxActive);
- stmtTxActive = false;
- DBUG_RETURN(savepoint(QMY_ROLLBACK_SAVEPOINT, SAVEPOINT_NAME));
- }
-
-
- /**
- Provide storage for generating error messages.
-
- This storage must persist until the error message is retrieved from the
- handler instance. It is for this reason that we associate it with the bridge.
-
- @return Pointer to heap storage of MYSQL_ERRMSG_SIZE bytes
- */
- char* getErrorStorage()
- {
- if (!connErrText)
- {
- connErrText = (char*)my_malloc(MYSQL_ERRMSG_SIZE, MYF(MY_WME));
- if (connErrText) connErrText[0] = 0;
- }
-
- return connErrText;
- }
-
- /**
- Free storage for generating error messages.
- */
- void freeErrorStorage()
- {
- if (likely(connErrText))
- {
- my_free(connErrText, MYF(0));
- connErrText = NULL;
- }
- }
-
-
- /**
- Store a file handle for later retrieval.
-
- If deallocateFile encounters a lock when trying to perform its operation,
- the file remains allocated but must be deallocated later. This function
- provides a way for the connection to "remember" that this deallocation is
- still needed.
-
- @param newname The name of the file to be added
- @param newhandle The handle associated with newname
-
- */
- void preserveHandle(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share)
- {
- pendingLockedHandles.add(newname, newhandle, share);
- }
-
- /**
- Retrieve a file handle stored by preserveHandle().
-
- @param name The name of the file to be retrieved.
-
- @return The handle associated with name
- */
- FILE_HANDLE findAndRemovePreservedHandle(const char* name, IBMDB2I_SHARE** share)
- {
- FILE_HANDLE hdl = pendingLockedHandles.findAndRemove(name, share);
- return hdl;
- }
-
- /**
- Indicate which error messages should be suppressed on the next API call
-
- These functions are useful for ensuring that the provided error numbers
- are returned if a failure occurs but do not cause a spurious error message
- to be returned.
-
- @return A pointer to this instance
- */
- db2i_ileBridge* expectErrors(int32 er1)
- {
- tacitErrors[0]=er1;
- return this;
- }
-
- db2i_ileBridge* expectErrors(int32 er1, int32 er2)
- {
- tacitErrors[0]=er1;
- tacitErrors[1]=er2;
- return this;
- }
-
- /**
- Obtain the IBM i system message that accompanied the last API failure.
-
- @return A pointer to the 7 character message ID.
- */
- static const char* getErrorMsgID()
- {
- return ((Qmy_Error_output_t*)parms()->outParms)->MsgId;
- }
-
- /**
- Convert an API error code into the equivalent MySQL error code (if any)
-
- @param rc The QMYSE API error code
-
- @return If an equivalent exists, the MySQL error code; else rc
- */
- static int32 translateErrorCode(int32 rc)
- {
- if (likely(rc == 0))
- return 0;
-
- switch (rc)
- {
- case QMY_ERR_KEY_NOT_FOUND:
- return HA_ERR_KEY_NOT_FOUND;
- case QMY_ERR_DUP_KEY:
- return HA_ERR_FOUND_DUPP_KEY;
- case QMY_ERR_END_OF_FILE:
- return HA_ERR_END_OF_FILE;
- case QMY_ERR_LOCK_TIMEOUT:
- return HA_ERR_LOCK_WAIT_TIMEOUT;
- case QMY_ERR_CST_VIOLATION:
- return HA_ERR_NO_REFERENCED_ROW;
- case QMY_ERR_TABLE_NOT_FOUND:
- return HA_ERR_NO_SUCH_TABLE;
- case QMY_ERR_NON_UNIQUE_KEY:
- return ER_DUP_ENTRY;
- case QMY_ERR_MSGID:
- {
- if (memcmp(getErrorMsgID(), DB2I_CPF503A, 7) == 0)
- return HA_ERR_ROW_IS_REFERENCED;
- if (memcmp(getErrorMsgID(), DB2I_SQL0538, 7) == 0)
- return HA_ERR_CANNOT_ADD_FOREIGN;
- }
- }
- return rc;
- }
-
-private:
-
- static db2i_ileBridge* createNewBridge(CONNECTION_HANDLE connID);
- static void destroyBridge(db2i_ileBridge* bridge);
- static int registerParmSpace(char* in, char* out);
- static int32 doIt();
- int32 doItWithLog();
-
- static _ILEpointer *functionSymbols; ///< Array of ILE function pointers
- CONNECTION_HANDLE cachedConnectionID; ///< The associated connection
- bool stmtTxActive; ///< Inside statement transaction
- char *connErrText; ///< Storage for error message
- int32 tacitErrors[TACIT_ERRORS_SIZE]; ///< List of errors to be suppressed
-
- static IleParms* initParmsForThread();
-
- /**
- Get space for passing parameters to the QMY_* APIs
-
- @details A fixed-length parameter passing space is associated with each
- pthread. This space is allocated and registered by initParmsForThread()
- the first time a pthread works with a bridge. The space is cached away
- and remains available until the pthread ends. It became necessary to
- disassociate the parameter space from the bridge in order to support
- future enhancements to MySQL that sever the one-to-one relationship between
- pthreads and user connections. The QMY_* APIs scope a registered parameter
- space to the thread that executes the register operation.
- */
- static IleParms* parms()
- {
- IleParms* p = my_pthread_getspecific_ptr(IleParms*, THR_ILEPARMS);
- if (likely(p))
- return p;
-
- return initParmsForThread();
- }
-
- class PreservedHandleList
- {
- friend db2i_ileBridge* db2i_ileBridge::createNewBridge(CONNECTION_HANDLE);
- public:
- void add(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share);
- FILE_HANDLE findAndRemove(const char* fileName, IBMDB2I_SHARE** share);
-
- private:
- struct NameHandlePair
- {
- char name[FN_REFLEN];
- FILE_HANDLE handle;
- IBMDB2I_SHARE* share;
- NameHandlePair* next;
- }* head;
- } pendingLockedHandles;
-
-
-#ifndef DBUG_OFF
- bool cachedStateIsCoherent()
- {
- return (current_thd->thread_id == cachedConnectionID);
- }
-
- friend void db2i_ileBridge::unregisterPtr(ILEMemHandle);
- friend void db2i_ileBridge::registerPtr(const void*, ILEMemHandle*);
- static uint32 registeredPtrs;
-#endif
-};
-
-
-
-#endif
diff --git a/storage/ibmdb2i/db2i_ioBuffers.cc b/storage/ibmdb2i/db2i_ioBuffers.cc
deleted file mode 100644
index 9525a6e34b5..00000000000
--- a/storage/ibmdb2i/db2i_ioBuffers.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_ioBuffers.h"
-
-/**
- Request another block of rows
-
- Request the next set of rows from DB2. This must only be called after
- newReadRequest().
-
- @param orientation The direction to use when reading through the table.
-*/
-void IOAsyncReadBuffer::loadNewRows(char orientation)
-{
- rewind();
- maxRows() = rowsToBlock;
-
- DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("Requesting %d rows, async = %d", rowsToBlock, readIsAsync));
-
- rc = getBridge()->expectErrors(QMY_ERR_END_OF_BLOCK, QMY_ERR_LOB_SPACE_TOO_SMALL)
- ->read(file,
- ptr(),
- accessIntent,
- commitLevel,
- orientation,
- readIsAsync,
- rrnList,
- 0,
- 0,
- 0);
-
- DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("recordsRead: %d, rc: %d", (uint32)rowCount(), rc));
-
-
- *releaseRowNeeded = true;
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- // This is really just an informational error, so we ignore it.
- rc = 0;
- DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("End of block signalled"));
- }
- else if (rc == QMY_ERR_END_OF_FILE)
- {
- // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked.
- rc = HA_ERR_END_OF_FILE;
- *releaseRowNeeded = false;
- }
- else if (rc == QMY_ERR_KEY_NOT_FOUND)
- {
- rc = HA_ERR_KEY_NOT_FOUND;
- *releaseRowNeeded = false;
- }
-
- if (rc) closePipe();
-}
-
-
-/**
- Empty the message pipe to prepare for another read.
-*/
-void IOAsyncReadBuffer::drainPipe()
-{
- DBUG_ASSERT(pipeState == PendingFullBufferMsg);
- PipeRpy_t msg[32];
- int bytes;
- PipeRpy_t* lastMsg;
- while ((bytes = read(msgPipe, msg, sizeof(msg))) > 0)
- {
- DBUG_PRINT("db2i_ioBuffers::drainPipe",("Pipe returned %d bytes", bytes));
- lastMsg = &msg[bytes / (sizeof(msg[0]))-1];
- if (lastMsg->CumRowCnt == maxRows() ||
- lastMsg->RtnCod != 0)
- {
- pipeState = ConsumedFullBufferMsg;
- break;
- }
-
- }
- DBUG_PRINT("db2i_ioBuffers::drainPipe",("rc = %d, rows = %d, max = %d", lastMsg->RtnCod, lastMsg->CumRowCnt, (uint32)maxRows()));
-}
-
-
-/**
- Poll the message pipe for async read messages
-
- Only valid in async
-
- @param orientation The direction to use when reading through the table.
-*/
-void IOAsyncReadBuffer::pollNextRow(char orientation)
-{
- DBUG_ASSERT(readIsAsync);
-
- // Handle the case in which the buffer is full.
- if (rowCount() == maxRows())
- {
- // If we haven't read to the end, exit here.
- if (readCursor < rowCount())
- return;
-
- if (pipeState == PendingFullBufferMsg)
- drainPipe();
- if (pipeState == ConsumedFullBufferMsg)
- loadNewRows(orientation);
- }
-
- if (!rc)
- {
- PipeRpy_t* lastMsg = NULL;
- while (true)
- {
- PipeRpy_t msg[32];
- int bytes = read(msgPipe, msg, sizeof(msg));
- DBUG_PRINT("db2i_ioBuffers::pollNextRow",("Pipe returned %d bytes", bytes));
-
- if (unlikely(bytes < 0))
- {
- DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("Error"));
- rc = errno;
- break;
- }
- else if (bytes == 0)
- break;
-
- DBUG_ASSERT(bytes % sizeof(msg[0]) == 0);
- lastMsg = &msg[bytes / (sizeof(msg[0]))-1];
-
- if (lastMsg->RtnCod || (lastMsg->CumRowCnt == usedRows()))
- {
- rc = lastMsg->RtnCod;
- break;
- }
- }
-
- *releaseRowNeeded = true;
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- rc = 0;
- else if (rc == QMY_ERR_END_OF_FILE)
- {
- // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked.
- rc = HA_ERR_END_OF_FILE;
- *releaseRowNeeded = false;
- }
- else if (rc == QMY_ERR_KEY_NOT_FOUND)
- {
- rc = HA_ERR_KEY_NOT_FOUND;
- *releaseRowNeeded = false;
- }
-
- if (lastMsg)
- DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("Good data: rc=%d; rows=%d; usedRows=%d", lastMsg->RtnCod, lastMsg->CumRowCnt, (uint32)usedRows()));
- if (lastMsg && likely(!rc))
- {
- if (lastMsg->CumRowCnt < maxRows())
- pipeState = PendingFullBufferMsg;
- else
- pipeState = ConsumedFullBufferMsg;
-
- DBUG_ASSERT(lastMsg->CumRowCnt <= usedRows());
-
- }
- DBUG_ASSERT(rowCount() <= getRowCapacity());
- }
- DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("filledRows: %d, rc: %d", rowCount(), rc));
- if (rc) closePipe();
-}
-
-
-/**
- Prepare for the destruction of the row buffer storage.
-*/
-void IOAsyncReadBuffer::prepForFree()
-{
- interruptRead();
- rewind();
- IORowBuffer::prepForFree();
-}
-
-
-/**
- Initialize the newly allocated storage.
-
- @param sizeChanged Indicates whether the storage capacity is being changed.
-*/
-void IOAsyncReadBuffer::initAfterAllocate(bool sizeChanged)
-{
- rewind();
-
- if (sizeChanged || ((void*)rrnList == NULL))
- rrnList.realloc(getRowCapacity() * sizeof(uint32));
-}
-
-
-/**
- Send an initial read request
-
- @param infile The file (table/index) being read from
- @param orientation The orientation to use for this read request
- @param rowsToBuffer The number of rows to request each time
- @param useAsync Whether reads should be performed asynchronously.
- @param key The key to use (if any)
- @param keyLength The length of key (if any)
- @param keyParts The number of columns in the key (if any)
-
-*/
-void IOAsyncReadBuffer::newReadRequest(FILE_HANDLE infile,
- char orientation,
- uint32 rowsToBuffer,
- bool useAsync,
- ILEMemHandle key,
- int keyLength,
- int keyParts)
-{
- DBUG_ENTER("db2i_ioBuffers::newReadRequest");
- DBUG_ASSERT(rowsToBuffer <= getRowCapacity());
-#ifndef DBUG_OFF
- if (readCursor < rowCount())
- DBUG_PRINT("PERF:",("Wasting %d buffered rows!\n", rowCount() - readCursor));
-#endif
-
- int fildes[2];
- int ileDescriptor = QMY_REUSE;
-
- interruptRead();
-
- if (likely(useAsync))
- {
- if (rowsToBuffer == 1)
- {
- // Async provides little or no benefit for single row reads, so we turn it off
- DBUG_PRINT("db2i_ioBuffers::newReadRequest", ("Disabling async"));
- useAsync = false;
- }
- else
- {
- rc = pipe(fildes);
- if (rc) DBUG_VOID_RETURN;
-
- // Translate the pipe write descriptor into the equivalent ILE descriptor
- rc = fstatx(fildes[1], (struct stat*)&ileDescriptor, sizeof(ileDescriptor), STX_XPFFD_PASE);
- if (rc)
- {
- close(fildes[0]);
- close(fildes[1]);
- DBUG_VOID_RETURN;
- }
- pipeState = Untouched;
- msgPipe = fildes[0];
-
- DBUG_PRINT("db2i_ioBuffers::newReadRequest", ("Opened pipe %d", fildes[0]));
- }
- }
-
- file = infile;
- readIsAsync = useAsync;
- rowsToBlock = rowsToBuffer;
-
- rewind();
- maxRows() = 1;
- rc = getBridge()->expectErrors(QMY_ERR_END_OF_BLOCK, QMY_ERR_LOB_SPACE_TOO_SMALL)
- ->read(file,
- ptr(),
- accessIntent,
- commitLevel,
- orientation,
- useAsync,
- rrnList,
- key,
- keyLength,
- keyParts,
- ileDescriptor);
-
- // Having shared the pipe with ILE, we relinquish our claim on the write end
- // of the pipe.
- if (useAsync)
- close(fildes[1]);
-
- // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked.
- if (rc == QMY_ERR_END_OF_FILE)
- {
- rc = HA_ERR_END_OF_FILE;
- *releaseRowNeeded = false;
- }
- else if (rc == QMY_ERR_KEY_NOT_FOUND)
- {
- if (rowCount())
- rc = HA_ERR_END_OF_FILE;
- else
- rc = HA_ERR_KEY_NOT_FOUND;
- *releaseRowNeeded = false;
- }
- else
- *releaseRowNeeded = true;
-
- DBUG_VOID_RETURN;
-}
diff --git a/storage/ibmdb2i/db2i_ioBuffers.h b/storage/ibmdb2i/db2i_ioBuffers.h
deleted file mode 100644
index 350d854f055..00000000000
--- a/storage/ibmdb2i/db2i_ioBuffers.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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.
-*/
-
-
-/**
- @file db2i_ioBuffers.h
-
- @brief Buffer classes used for interacting with QMYSE read/write buffers.
-
-*/
-
-
-#include "db2i_validatedPointer.h"
-#include "mysql_priv.h"
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <as400_types.h>
-
-// Needed for compilers which do not include fstatx in standard headers.
-extern "C" int fstatx(int, struct stat *, int, int);
-
-/**
- Basic row buffer
-
- Provides the basic structure and methods needed for communicating
- with QMYSE I/O APIs.
-
- @details All QMYSE I/O apis use a buffer that is structured as two integer
- row counts (max and used) and storage for some number of rows. The row counts
- are both input and output for the API, and their usage depends on the
- particular API invoked. This class encapsulates that buffer definition.
-*/
-class IORowBuffer
-{
- public:
- IORowBuffer() : allocSize(0), rowLength(0) {;}
- ~IORowBuffer() { freeBuf(); }
- ValidatedPointer<char>& ptr() { return data; }
-
- /**
- Sets up the buffer to hold the size indicated.
-
- @param rowLen length of the rows that will be stored in this buffer
- @param nullMapOffset position of null map within each row
- @param size buffer size requested
- */
- void allocBuf(uint32 rowLen, uint16 nullMapOffset, uint32 size)
- {
- nullOffset = nullMapOffset;
- uint32 newSize = size + sizeof(BufferHdr_t);
- // If the internal structure of the row is changing, we need to
- // remember this and notify the subclasses via initAfterAllocate();
- bool formatChanged = ((size/rowLen) != rowCapacity);
-
- if (newSize > allocSize)
- {
- this->freeBuf();
- data.alloc(newSize);
- if (likely((void*)data))
- allocSize = newSize;
- }
-
- if (likely((void*)data))
- {
- DBUG_ASSERT((uint64)(void*)data % 16 == 0);
- rowLength = rowLen;
- rowCapacity = size / rowLength;
- initAfterAllocate(formatChanged);
- }
- else
- {
- allocSize = 0;
- rowCapacity = 0;
- }
-
- DBUG_PRINT("db2i_ioBuffers::allocBuf",("rowCapacity = %d", rowCapacity));
- }
-
- void zeroBuf()
- {
- memset(data, 0, allocSize);
- }
-
- void freeBuf()
- {
- if (likely(allocSize))
- {
- prepForFree();
- DBUG_PRINT("IORowBuffer::freeBuf",("Freeing 0x%p", (char*)data));
- data.dealloc();
- }
- }
-
- char* getRowN(uint32 n)
- {
- if (unlikely(n >= getRowCapacity()))
- return NULL;
- return (char*)data + sizeof(BufferHdr_t) + (rowLength * n);
- };
-
- uint32 getRowCapacity() const {return rowCapacity;}
- uint32 getRowNullOffset() const {return nullOffset;}
- uint32 getRowLength() const {return rowLength;}
-
- protected:
- /**
- Called prior to freeing buffer storage so that subclasses can do
- any required cleanup
- */
- virtual void prepForFree()
- {
- allocSize = 0;
- rowCapacity = 0;
- }
-
- /**
- Called after buffer storage so that subclasses can do any required setup.
- */
- virtual void initAfterAllocate(bool sizeChanged) { return;}
-
- ValidatedPointer<char> data;
- uint32 allocSize;
- uint32 rowCapacity;
- uint32 rowLength;
- uint16 nullOffset;
- uint32& usedRows() const { return ((BufferHdr_t*)(char*)data)->UsedRowCnt; }
- uint32& maxRows() const {return ((BufferHdr_t*)(char*)data)->MaxRowCnt; }
-};
-
-
-/**
- Write buffer
-
- Implements methods for inserting data into a row buffer for use with the
- QMY_WRITE and QMY_UPDATE APIs.
-
- @details The max row count defines how many rows are in the buffer. The used
- row count is updated by QMYSE to indicate how many rows have been
- successfully written.
-*/
-class IOWriteBuffer : public IORowBuffer
-{
- public:
- bool endOfBuffer() const {return (maxRows() == getRowCapacity());}
-
- char* addRow()
- {
- return getRowN(maxRows()++);
- }
-
- void resetAfterWrite()
- {
- maxRows() = 0;
- }
-
- void deleteRow()
- {
- --maxRows();
- }
-
- uint32 rowCount() const {return maxRows();}
-
- uint32 rowsWritten() const {return usedRows()-1;}
-
- private:
- void initAfterAllocate(bool sizeChanged) {maxRows() = 0; usedRows() = 0;}
-};
-
-
-/**
- Read buffer
-
- Implements methods for reading data from and managing a row buffer for use
- with the QMY_READ APIs. This is primarily for use with metainformation queries.
-*/
-class IOReadBuffer : public IORowBuffer
-{
- public:
-
- IOReadBuffer() {;}
- IOReadBuffer(uint32 rows, uint32 rowLength)
- {
- allocBuf(rows, 0, rows * rowLength);
- maxRows() = rows;
- }
-
- uint32 rowCount() {return usedRows();}
- void setRowsToProcess(uint32 rows) { maxRows() = rows; }
-};
-
-
-/**
- Read buffer
-
- Implements methods for reading data from and managing a row buffer for use
- with the QMY_READ APIs.
-
- @details This class supports both sync and async read modes. The max row
- count defines the number of rows that are requested to be read. The used row
- count defines how many rows have been read. Sync mode is reasonably
- straightforward, but async mode has a complex system of communicating with
- QMYSE that is optimized for low latency. In async mode, the used row count is
- updated continuously by QMYSE as rows are read. At the same time, messages are
- sent to the associated pipe indicating that a row has been read. As long as
- the internal read cursor lags behind the used row count, the pipe is never
- consulted. But if the internal read cursor "catches up to" the used row count,
- then we block on the pipe until we find a message indicating that a new row
- has been read or that an error has occurred.
-*/
-class IOAsyncReadBuffer : public IOReadBuffer
-{
- public:
- IOAsyncReadBuffer() :
- file(0), readIsAsync(false), msgPipe(QMY_REUSE), bridge(NULL)
- {
- }
-
- ~IOAsyncReadBuffer()
- {
- interruptRead();
- rrnList.dealloc();
- }
-
-
- /**
- Signal read operation complete
-
- Indicates that the storage engine requires no more data from the table.
- Must be called between calls to newReadRequest().
- */
- void endRead()
- {
-#ifndef DBUG_OFF
- if (readCursor < rowCount())
- DBUG_PRINT("PERF:",("Wasting %d buffered rows!\n", rowCount() - readCursor));
-#endif
- interruptRead();
-
- file = 0;
- bridge = NULL;
- }
-
- /**
- Update data that may change on each read operation
- */
- void update(char newAccessIntent,
- bool* newReleaseRowNeeded,
- char commitLvl)
- {
- accessIntent = newAccessIntent;
- releaseRowNeeded = newReleaseRowNeeded;
- commitLevel = commitLvl;
- }
-
- /**
- Read the next row in the table.
-
- Return a pointer to the next row in the table, where "next" is defined
- by the orientation.
-
- @param orientaton
- @param[out] rrn The relative record number of the row returned. Not reliable
- if NULL is returned by this function.
-
- @return Pointer to the row. Null if no more rows are available or an error
- occurred.
- */
- char* readNextRow(char orientation, uint32& rrn)
- {
- DBUG_PRINT("db2i_ioBuffers::readNextRow", ("readCursor: %d, filledRows: %d, rc: %d", readCursor, rowCount(), rc));
-
- while (readCursor >= rowCount() && !rc)
- {
- if (!readIsAsync)
- loadNewRows(orientation);
- else
- pollNextRow(orientation);
- }
-
- if (readCursor >= rowCount())
- return NULL;
-
- rrn = rrnList[readCursor];
- return getRowN(readCursor++);
- }
-
- /**
- Retrieve the return code generated by the last operation.
-
- @return The return code, translated to the appropriate HA_ERR_*
- value if possible.
- */
- int32 lastrc()
- {
- return db2i_ileBridge::translateErrorCode(rc);
- }
-
- void rewind()
- {
- readCursor = 0;
- rc = 0;
- usedRows() = 0;
- }
-
- bool reachedEOD() { return EOD; }
-
- void newReadRequest(FILE_HANDLE infile,
- char orientation,
- uint32 rowsToBuffer,
- bool useAsync,
- ILEMemHandle key,
- int keyLength,
- int keyParts);
-
- private:
-
- /**
- End any running async read operation.
- */
- void interruptRead()
- {
- closePipe();
- if (file && readIsAsync && (rc == 0) && (rowCount() < getRowCapacity()))
- {
- DBUG_PRINT("IOReadBuffer::interruptRead", ("PERF: Interrupting %d", (uint32)file));
- getBridge()->readInterrupt(file);
- }
- }
-
- void closePipe()
- {
- if (msgPipe != QMY_REUSE)
- {
- DBUG_PRINT("db2i_ioBuffers::closePipe", ("Closing pipe %d", msgPipe));
- close(msgPipe);
- msgPipe = QMY_REUSE;
- }
- }
-
- /**
- Get a pointer to the active ILE bridge.
-
- Getting the bridge pointer is (relatively) expensive, so we cache
- it off for each operation.
- */
- db2i_ileBridge* getBridge()
- {
- if (unlikely(bridge == NULL))
- {
- bridge = db2i_ileBridge::getBridgeForThread();
- }
- return bridge;
- }
-
- void drainPipe();
- void pollNextRow(char orientation);
- void prepForFree();
- void initAfterAllocate(bool sizeChanged);
- void loadNewRows(char orientation);
-
-
- uint32 readCursor; // Read position within buffer
- int32 rc; // Last return code received
- ValidatedPointer<uint32> rrnList; // Receiver for list of rrns
- char accessIntent; // The access intent for this read
- char commitLevel; // What isolation level should be used
- char EOD; // Whether end-of-data was hit
- char readIsAsync; // Are reads to be done asynchronously?
- bool* releaseRowNeeded;
- /* Does the caller need to release the current row when finished reading */
- FILE_HANDLE file; // The file to be read
- int msgPipe;
- /* The read descriptor of the pipe used to pass messages during async reads */
- db2i_ileBridge* bridge; // Cached pointer to bridge
- uint32 rowsToBlock; // Number of rows to request
- enum
- {
- ConsumedFullBufferMsg,
- PendingFullBufferMsg,
- Untouched
- } pipeState;
- /* The state of the async read message pipe */
-};
-
diff --git a/storage/ibmdb2i/db2i_misc.h b/storage/ibmdb2i/db2i_misc.h
deleted file mode 100644
index f0b527aaad0..00000000000
--- a/storage/ibmdb2i/db2i_misc.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_MISC_H
-#define DB2I_MISC_H
-
-/**
- Undelimit quote-delimited DB2 names in-place
-*/
-void stripExtraQuotes(char* name, uint maxLen)
-{
- char* oldName = (char*)sql_strdup(name);
- uint i = 0;
- uint j = 0;
- do
- {
- name[j] = oldName[i];
- if (oldName[i] == '"' && oldName[i+1] == '"')
- ++i;
- } while (++j < maxLen && oldName[++i]);
-
- if (j == maxLen)
- --j;
- name[j] = 0;
-}
-
-/**
- Convert a MySQL identifier name into a DB2 compatible format
-
- @parm input The MySQL name
- @parm output The DB2 name
- @parm outlen The amount of space allocated for output
- @parm delimit Should delimiting quotes be placed around the converted name?
- @parm delimitQuotes Should quotes in the MySQL be delimited with additional quotes?
-
- @return FALSE if output was too small and name was truncated; TRUE otherwise
-*/
-bool convertMySQLNameToDB2Name(const char* input,
- char* output,
- size_t outlen,
- bool delimit = true,
- bool delimitQuotes = true)
-{
- uint o = 0;
- if (delimit)
- output[o++] = '"';
-
- uint i = 0;
- do
- {
- output[o] = input[i];
- if (delimitQuotes && input[i] == '"')
- output[++o] = '"';
- } while (++o < outlen-2 && input[++i]);
-
- if (delimit)
- output[o++] = '"';
- output[min(o, outlen-1)] = 0; // This isn't the most user-friendly way to handle overflows,
- // but at least its safe.
- return (o <= outlen-1);
-}
-
-bool isOrdinaryIdentifier(const char* s)
-{
- while (*s)
- {
- if (my_isupper(system_charset_info, *s) ||
- my_isdigit(system_charset_info, *s) ||
- (*s == '_') ||
- (*s == '@') ||
- (*s == '$') ||
- (*s == '#') ||
- (*s == '"'))
- ++s;
- else
- return false;
- }
- return true;
-}
-
-/**
- Fill memory with a 16-bit word.
-
- @param p Pointer to space to fill.
- @param v Value to fill
- @param l Length of space (in 16-bit words)
-*/
-void memset16(void* p, uint16 v, size_t l)
-{
- uint16* p2=(uint16*)p;
- while (l--)
- {
- *(p2++) = v;
- }
-}
-
-#endif
diff --git a/storage/ibmdb2i/db2i_myconv.cc b/storage/ibmdb2i/db2i_myconv.cc
deleted file mode 100644
index 7be6e1236cd..00000000000
--- a/storage/ibmdb2i/db2i_myconv.cc
+++ /dev/null
@@ -1,1498 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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.
-*/
-
-/**
- @file
-
- @brief A direct map optimization of iconv and related functions
- This was show to significantly reduce character conversion cost
- for short strings when compared to calling iconv system code.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <errno.h>
-#include <iconv.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <string.h>
-#include <as400_protos.h>
-
-#include "db2i_myconv.h"
-#include "db2i_global.h"
-
-int32_t myconvDebug=0;
-
-static char szGetTimeString[20];
-static char * GetTimeString(time_t now)
-{
- struct tm * tm;
-
- now = time(&now);
- tm = (struct tm *) localtime(&now);
- sprintf(szGetTimeString, "%04d/%02d/%02d %02d:%02d:%02d",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- return szGetTimeString;
-}
-
-static MEM_ROOT dmapMemRoot;
-
-void initMyconv()
-{
- init_alloc_root(&dmapMemRoot, 0x200, 0);
-}
-
-void cleanupMyconv()
-{
- free_root(&dmapMemRoot,0);
-}
-
-
-#ifdef DEBUG
-/* type: */
-#define STDOUT_WITH_TIME -1 /* to stdout with time */
-#define STDERR_WITH_TIME -2 /* to stderr with time */
-#define STDOUT_WO_TIME 1 /* : to stdout */
-#define STDERR_WO_TIME 2 /* : to stderr */
-
-
-static void MyPrintf(long type,
- char * fmt, ...)
-{
- char StdoutFN[256];
- va_list ap;
- char * p;
- time_t now;
- FILE * fd=stderr;
-
- if (type < 0)
- {
- now = time(&now);
- fprintf(fd, "%s ", GetTimeString(now));
- }
- va_start(ap, fmt);
- vfprintf(fd, fmt, ap);
- va_end(ap);
-}
-#endif
-
-
-
-
-#define MAX_CONVERTER 128
-
-mycstoccsid(const char* pname)
-{
- if (strcmp(pname, "UTF-16")==0)
- return 1200;
- else if (strcmp(pname, "big5")==0)
- return 950;
- else
- return cstoccsid(pname);
-}
-#define cstoccsid mycstoccsid
-
-static struct __myconv_rec myconv_rec [MAX_CONVERTER];
-static struct __dmap_rec dmap_rec [MAX_CONVERTER];
-
-static int dmap_open(const char * to,
- const char * from,
- const int32_t idx)
-{
- if (myconvIsSBCS(from) && myconvIsSBCS(to)) {
- dmap_rec[idx].codingSchema = DMAP_S2S;
- if ((dmap_rec[idx].dmapS2S = (uchar *) alloc_root(&dmapMemRoot, 0x100)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_S2S, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapS2S, 0x00, 0x100);
- myconv_rec[idx].allocatedSize=0x100;
-
- {
- char dmapSrc[0x100];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft=0x100;
- size_t outBytesLeft=0x100;
- size_t len;
- char * inBuf=dmapSrc;
- char * outBuf=(char *) dmap_rec[idx].dmapS2S;
-
- if ((cd = iconv_open(to, from)) == (iconv_t) -1) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- inBytesLeft = 0x100;
- for (i = 0; i < inBytesLeft; ++i)
- dmapSrc[i]=i;
-
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d: iconv() returns %d, errno = %d in %s at %d\n",
- to, from, idx, DMAP_S2S, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "inBytesLeft = %d, inBuf - dmapSrc = %d\n", inBytesLeft, inBuf-dmapSrc);
- MyPrintf(STDERR_WITH_TIME,
- "outBytesLeft = %d, outBuf - dmapS2S = %d\n", outBytesLeft, outBuf-(char *) dmap_rec[idx].dmapS2S);
- }
- if ((inBytesLeft == 86 || inBytesLeft == 64 || inBytesLeft == 1) &&
- memcmp(from, "IBM-1256", 9) == 0 &&
- memcmp(to, "IBM-420", 8) == 0) {
- /* Known problem for IBM-1256_IBM-420 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- } else if ((inBytesLeft == 173 || inBytesLeft == 172 ||
- inBytesLeft == 74 || inBytesLeft == 73 ||
- inBytesLeft == 52 || inBytesLeft == 50 ||
- inBytesLeft == 31 || inBytesLeft == 20 ||
- inBytesLeft == 6) &&
- memcmp(to, "IBM-1256", 9) == 0 &&
- memcmp(from, "IBM-420", 8) == 0) {
- /* Known problem for IBM-420_IBM-1256 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- } else if ((128 >= inBytesLeft) &&
- memcmp(to, "IBM-037", 8) == 0 &&
- memcmp(from, "IBM-367", 8) == 0) {
- /* Known problem for IBM-367_IBM-037 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- } else if (((1 <= inBytesLeft && inBytesLeft <= 4) || (97 <= inBytesLeft && inBytesLeft <= 128)) &&
- memcmp(to, "IBM-838", 8) == 0 &&
- memcmp(from, "TIS-620", 8) == 0) {
- /* Known problem for TIS-620_IBM-838 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- }
- iconv_close(cd);
- return -1;
-#else
- /* Tolerant to undefined conversions for any converter */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
-#endif
- }
- } while (inBytesLeft > 0);
-
- if (myconvIsISO(to))
- myconv_rec[idx].subS=0x1A;
- else if (myconvIsASCII(to))
- myconv_rec[idx].subS=0x7F;
- else if (myconvIsEBCDIC(to))
- myconv_rec[idx].subS=0x3F;
-
- if (myconvIsISO(from))
- myconv_rec[idx].srcSubS=0x1A;
- else if (myconvIsASCII(from))
- myconv_rec[idx].srcSubS=0x7F;
- else if (myconvIsEBCDIC(from))
- myconv_rec[idx].srcSubS=0x3F;
-
- iconv_close(cd);
- }
- } else if (((myconvIsSBCS(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_S2U)) ||
- ((myconvIsSBCS(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_S28))) {
- int i;
-
- /* single byte mapping */
- if ((dmap_rec[idx].dmapD12U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_S2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapD12U, 0x00, 0x100 * 2);
- myconv_rec[idx].allocatedSize=0x100 * 2;
-
-
- {
- char dmapSrc[2];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
- char SS=0x1A;
-#ifdef support_surrogate
- if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- dmapSrc[0]=i;
- inBuf=dmapSrc;
- inBytesLeft=1;
- outBuf=(char *) &(dmap_rec[idx].dmapD12U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if ((errno == EILSEQ || errno == EINVAL) &&
- inBytesLeft == 1 &&
- outBytesLeft == 2) {
- continue;
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%02x,%d,%02x%02x,%d), errno = %d in %s at %d\n",
- to, from, idx, dmapSrc[0], 1,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1], 2,
- errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "inBytesLeft=%d, outBytesLeft=%d, %02x%02x\n",
- inBytesLeft, outBytesLeft,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1]);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- dmap_rec[idx].dmapD12U[i]=0x0000;
- }
- if (dmap_rec[idx].dmapE02U[i] == 0x001A && /* pick the first one */
- myconv_rec[idx].srcSubS == 0x00) {
- myconv_rec[idx].srcSubS=i;
- }
- }
- iconv_close(cd);
- }
- myconv_rec[idx].subS=0x1A;
- myconv_rec[idx].subD=0xFFFD;
-
-
- } else if (((myconvIsUCS2(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_U2S)) ||
- ((myconvIsUTF16(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_T2S)) ||
- ((myconvIsUTF8(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_82S))) {
- /* UTF-16 -> SBCS, the direct map a bit of waste of space,
- * binary search may be reasonable alternative
- */
- if ((dmap_rec[idx].dmapU2S = (uchar *) alloc_root(&dmapMemRoot, 0x10000 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2S, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2S, 0x00, 0x10000);
- myconv_rec[idx].allocatedSize=(0x10000 * 2);
-
- {
- iconv_t cd;
- int32_t i;
-
-#ifdef support_surrogate
- if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- UniChar dmapSrc[0x100];
- int32_t j;
- for (j = 0; j < 0x100; ++j) {
- dmapSrc[j]=i * 0x100 + j;
- }
- char * inBuf=(char *) dmapSrc;
- char * outBuf=(char *) &(dmap_rec[idx].dmapU2S[i*0x100]);
- size_t inBytesLeft=sizeof(dmapSrc);
- size_t outBytesLeft=0x100;
- size_t len;
-
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (inBytesLeft == 0 && outBytesLeft == 0) { /* a number of substitution returns */
- continue;
- }
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- from, to, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "iconv() retuns %d, errno=%d, InBytesLeft=%d, OutBytesLeft=%d\n",
- len, errno, inBytesLeft, outBytesLeft, __FILE__,__LINE__);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- iconv_close(cd);
-
- myconv_rec[idx].subS = dmap_rec[idx].dmapU2S[0x1A];
- myconv_rec[idx].subD = dmap_rec[idx].dmapU2S[0xFFFD];
- myconv_rec[idx].srcSubS = 0x1A;
- myconv_rec[idx].srcSubD = 0xFFFD;
- }
-
-
-
- } else if (((myconvIsDBCS(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_D2U)) ||
- ((myconvIsDBCS(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_D28))) {
- int i;
- /* single byte mapping */
- if ((dmap_rec[idx].dmapD12U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_D2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapD12U, 0x00, 0x100 * 2);
-
- /* double byte mapping, assume 7 bit ASCII is not use as the first byte of DBCS. */
- if ((dmap_rec[idx].dmapD22U = (UniChar *) alloc_root(&dmapMemRoot, 0x8000 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_D2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapD22U, 0x00, 0x8000 * 2);
-
- myconv_rec[idx].allocatedSize=(0x100 + 0x8000) * 2;
-
-
- {
- char dmapSrc[2];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
- char SS=0x1A;
-
-#ifdef support_surrogate
- if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- dmapSrc[0]=i;
- inBuf=dmapSrc;
- inBytesLeft=1;
- outBuf=(char *) (&dmap_rec[idx].dmapD12U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if ((errno == EILSEQ || errno == EINVAL) &&
- inBytesLeft == 1 &&
- outBytesLeft == 2) {
- continue;
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%02x,%d,%02x%02x,%d), errno = %d in %s at %d\n",
- to, from, idx, dmapSrc[0], 1,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1], 2,
- errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "inBytesLeft=%d, outBytesLeft=%d, %02x%02x\n",
- inBytesLeft, outBytesLeft,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1]);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- dmap_rec[idx].dmapD12U[i]=0x0000;
- }
- if (dmap_rec[idx].dmapD12U[i] == 0x001A && /* pick the first one */
- myconv_rec[idx].srcSubS == 0x00) {
- myconv_rec[idx].srcSubS=i;
- }
- }
-
-
- for (i = 0x80; i < 0x100; ++i) {
- int j;
- if (dmap_rec[idx].dmapD12U[i] != 0x0000)
- continue;
- for (j = 0x01; j < 0x100; ++j) {
- dmapSrc[0]=i;
- dmapSrc[1]=j;
- int offset = i-0x80;
- offset<<=8;
- offset+=j;
-
- inBuf=dmapSrc;
- inBytesLeft=2;
- outBuf=(char *) &(dmap_rec[idx].dmapD22U[offset]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (inBytesLeft == 2 && outBytesLeft == 2 && (errno == EILSEQ || errno == EINVAL)) {
- ; /* invalid DBCS character, dmapDD2U[offset] remains 0x0000 */
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%p,2,%p,2), errno = %d in %s at %d\n",
- to, from, idx,
- dmapSrc, &(dmap_rec[idx].dmapD22U[offset]),
- errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME,
- "iconv(cd,0x%02x%02x,2,0x%04x,2) returns %d, inBytesLeft=%d, outBytesLeft=%d\n",
- dmapSrc[0], dmapSrc[1],
- dmap_rec[idx].dmapD22U[offset],
- len, inBytesLeft, outBytesLeft);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- } else {
-#ifdef TRACE_DMAP
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf=%02X%02X%02X, outBytesLeft=%d\n",
- i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1],
- inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft);
- MyPrintf(STDERR_WITH_TIME,
- "&dmapSrc=%p, inBuf=%p, %p, outBuf=%p\n",
- dmapSrc, inBuf, dmap_rec[idx].dmapU2M3 + (i - 0x80) * 2, outBuf);
- }
-#endif
- }
- }
- if (dmap_rec[idx].dmapD12U[i] == 0xFFFD) { /* pick the last one */
- myconv_rec[idx].srcSubD=i* 0x100 + j;
- }
- }
- iconv_close(cd);
- }
-
- myconv_rec[idx].subS=0x1A;
- myconv_rec[idx].subD=0xFFFD;
- myconv_rec[idx].srcSubD=0xFCFC;
-
-
- } else if (((myconvIsUCS2(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_U2D)) ||
- ((myconvIsUTF16(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_T2D)) ||
- ((myconvIsUTF8(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_82D))) {
- /* UTF-16 -> DBCS single/double byte */
- /* A single table will cover all characters, assuming no second byte is 0x00. */
- if ((dmap_rec[idx].dmapU2D = (uchar *) alloc_root(&dmapMemRoot, 0x10000 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2D, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- memset(dmap_rec[idx].dmapU2D, 0x00, 0x10000 * 2);
- myconv_rec[idx].allocatedSize=(0x10000 * 2);
-
- {
- UniChar dmapSrc[1];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
-
-#ifdef support_surrogate
- if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- /* easy implementation, convert 1 Unicode character at one time. */
- /* If the open performance is an issue, convert a chunk such as 128 chracters. */
- /* if the converted length is not the same as the original, convert one by one. */
- (dmap_rec[idx].dmapU2D)[0x0000]=0x00;
- for (i = 1; i < 0x10000; ++i) {
- dmapSrc[0]=i;
- inBuf=(char *) dmapSrc;
- inBytesLeft=2;
- outBuf=(char *) &((dmap_rec[idx].dmapU2D)[2*i]);
- outBytesLeft=2;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (len == 1 && inBytesLeft == 0 && outBytesLeft == 1 && (dmap_rec[idx].dmapU2D)[2*i] == 0x1A) {
- /* UCS-2_TIS-620:0x0080 => 0x1A, converted to SBCS replacement character */
- (dmap_rec[idx].dmapU2D)[2*i+1]=0x00;
- break;
- } else if (len == 1 && inBytesLeft == 0 && outBytesLeft == 0) {
- break;
- }
- if (errno == EILSEQ || errno == EINVAL) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME,
- "iconv(cd,%04x,2,%02x%02x,2) returns inBytesLeft=%d, outBytesLeft=%d\n",
- dmapSrc[0],
- (dmap_rec[idx].dmapU2D)[2*i], (dmap_rec[idx].dmapU2D)[2*i+1],
- inBytesLeft, outBytesLeft);
- if (outBuf - (char *) dmap_rec[idx].dmapU2M2 > 1)
- MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- inBuf+=2;
- inBytesLeft-=2;
- memcpy(outBuf, (char *) &(myconv_rec[idx].subD), 2);
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "[%d] dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- i, to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME,
- "iconv(cd,%04x,2,%02x%02x,2) returns %d inBytesLeft=%d, outBytesLeft=%d\n",
- dmapSrc[0],
- (dmap_rec[idx].dmapU2D)[2*i],
- (dmap_rec[idx].dmapU2D)[2*i+1],
- len, inBytesLeft,outBytesLeft);
- if (i == 1) {
- MyPrintf(STDERR_WO_TIME,
- " inBuf [-1..2]=%02x%02x%02x%02x\n",
- inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- MyPrintf(STDERR_WO_TIME,
- " outBuf [-1..2]=%02x%02x%02x%02x\n",
- outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- } else {
- MyPrintf(STDERR_WO_TIME,
- " inBuf [-2..2]=%02x%02x%02x%02x%02x\n",
- inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- MyPrintf(STDERR_WO_TIME,
- " outBuf [-2..2]=%02x%02x%02x%02x%02x\n",
- outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- if (len == 0 && inBytesLeft == 0 && outBytesLeft == 1) { /* converted to SBCS */
- (dmap_rec[idx].dmapU2D)[2*i+1]=0x00;
- break;
- }
- }
- } while (inBytesLeft > 0);
- }
- iconv_close(cd);
- myconv_rec[idx].subS = dmap_rec[idx].dmapU2D[2*0x1A];
- myconv_rec[idx].subD = dmap_rec[idx].dmapU2D[2*0xFFFD] * 0x100
- + dmap_rec[idx].dmapU2D[2*0xFFFD+1];
- myconv_rec[idx].srcSubS = 0x1A;
- myconv_rec[idx].srcSubD = 0xFFFD;
- }
-
-
- } else if (((myconvIsEUC(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_E2U)) ||
- ((myconvIsEUC(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_E28))) {
- int i;
- /* S0: 0x00 - 0x7F */
- if ((dmap_rec[idx].dmapE02U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE02U, 0x00, 0x100 * 2);
-
- /* S1: 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapE12U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x60 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE12U, 0x00, 0x60 * 0x60 * 2);
-
- /* SS2: 0x8E + 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapE22U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x61 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE22U, 0x00, 0x60 * 0x61 * 2);
-
- /* SS3: 0x8F + 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapE32U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x61 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE32U, 0x00, 0x60 * 0x61 * 2);
-
- myconv_rec[idx].allocatedSize=(0x100 + 0x60 * 0x60 + 0x60 * 0x61* 2) * 2;
-
-
- {
- char dmapSrc[0x60 * 0x60 * 3];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
- char SS=0x8E;
-
-#ifdef support_surrogate
- if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- dmapSrc[0]=i;
- inBuf=dmapSrc;
- inBytesLeft=1;
- outBuf=(char *) (&dmap_rec[idx].dmapE02U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- }
-#endif
- dmap_rec[idx].dmapE02U[i]=0x0000;
- }
- if (dmap_rec[idx].dmapE02U[i] == 0x001A && /* pick the first one */
- myconv_rec[idx].srcSubS == 0x00) {
- myconv_rec[idx].srcSubS=i;
- }
- }
-
-
- inBuf=dmapSrc;
- for (i = 0; i < 0x60; ++i) {
- int j;
- for (j = 0; j < 0x60; ++j) {
- *inBuf=i+0xA0;
- ++inBuf;
- *inBuf=j+0xA0;
- ++inBuf;
- }
- }
- inBuf=dmapSrc;
- inBytesLeft=0x60 * 0x60 * 2;
- outBuf=(char *) dmap_rec[idx].dmapE12U;
- outBytesLeft=0x60 * 0x60 * 2;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (errno == EILSEQ) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft);
- if (inBuf - dmapSrc > 1 && inBuf - dmapSrc <= sizeof(dmapSrc) - 2)
- MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]);
- if (outBuf - (char *) dmap_rec[idx].dmapE12U > 1)
- MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- inBuf+=2;
- inBytesLeft-=2;
- outBuf[0]=0x00;
- outBuf[1]=0x00;
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- } while (inBytesLeft > 0);
-
- /* SS2: 0x8E + 1 or 2 bytes */
- /* SS3: 0x8E + 1 or 2 bytes */
- while (SS != 0x00) {
- int32_t numSuccess=0;
- for (i = 0; i < 0x60; ++i) {
- inBuf=dmapSrc;
- inBuf[0]=SS;
- inBuf[1]=i+0xA0;
- inBytesLeft=2;
- if (SS == 0x8E)
- outBuf=(char *) &(dmap_rec[idx].dmapE22U[i]);
- else
- outBuf=(char *) &(dmap_rec[idx].dmapE32U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (SS == 0x8E)
- dmap_rec[idx].dmapE22U[i]=0x0000;
- else
- dmap_rec[idx].dmapE32U[i]=0x0000;
- } else {
- ++numSuccess;
- }
- }
- if (numSuccess == 0) { /* SS2 is 2 bytes */
- inBuf=dmapSrc;
- for (i = 0; i < 0x60; ++i) {
- int j;
- for (j = 0; j < 0x60; ++j) {
- *inBuf=SS;
- ++inBuf;
- *inBuf=i+0xA0;
- ++inBuf;
- *inBuf=j+0xA0;
- ++inBuf;
- }
- }
- inBuf=dmapSrc;
- inBytesLeft=0x60 * 0x60 * 3;
- if (SS == 0x8E)
- outBuf=(char *) &(dmap_rec[idx].dmapE22U[0x60]);
- else
- outBuf=(char *) &(dmap_rec[idx].dmapE32U[0x60]);
- outBytesLeft=0x60 * 0x60 * 2;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "%02X:dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- SS, to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft);
- if (inBuf - dmapSrc > 1 && inBuf - dmapSrc <= sizeof(dmapSrc) - 2)
- MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]);
- }
-#endif
- if (errno == EILSEQ || errno == EINVAL) {
- inBuf+=3;
- inBytesLeft-=3;
- outBuf[0]=0x00;
- outBuf[1]=0x00;
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "%02X:dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- SS, to, from, idx, errno, __FILE__,__LINE__);
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- } while (inBytesLeft > 0);
- }
- if (SS == 0x8E)
- SS=0x8F;
- else
- SS = 0x00;
- }
- iconv_close(cd);
-
- myconv_rec[idx].subS=0x1A;
- myconv_rec[idx].subD=0xFFFD;
- for (i = 0; i < 0x80; ++i) {
- if (dmap_rec[idx].dmapE02U[i] == 0x001A) {
- myconv_rec[idx].srcSubS=i; /* pick the first one */
- break;
- }
- }
-
- for (i = 0; i < 0x60 * 0x60; ++i) {
- if (dmap_rec[idx].dmapE12U[i] == 0xFFFD) {
- uchar byte1=i / 0x60;
- uchar byte2=i % 0x60;
- myconv_rec[idx].srcSubD=(byte1 + 0xA0) * 0x100 + (byte2 + 0xA0); /* pick the last one */
- }
- }
-
- }
-
- } else if (((myconvIsUCS2(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_U2E)) ||
- ((myconvIsUTF16(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_T2E)) ||
- ((myconvIsUTF8(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_82E))) {
- /* S0: 0x00 - 0xFF */
- if ((dmap_rec[idx].dmapU2S = (uchar *) alloc_root(&dmapMemRoot, 0x100)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2S, 0x00, 0x100);
-
- /* U0080 - UFFFF -> S1: 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapU2M2 = (uchar *) alloc_root(&dmapMemRoot, 0xFF80 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2M2, 0x00, 0xFF80 * 2);
-
- /* U0080 - UFFFF -> SS2: 0x8E + 0xA0 - 0xFF, 0xA0 - 0xFF
- * SS3: 0x8F + 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapU2M3 = (uchar *) alloc_root(&dmapMemRoot, 0xFF80 * 3)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2M3, 0x00, 0xFF80 * 3);
- myconv_rec[idx].allocatedSize=(0x100 + 0xFF80 * 2 + 0xFF80 * 3);
-
- {
- UniChar dmapSrc[0x80];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
-
-#ifdef support_surrogate
- if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x80; ++i)
- dmapSrc[i]=i;
- inBuf=(char *) dmapSrc;
- inBytesLeft=0x80 * 2;
- outBuf=(char *) dmap_rec[idx].dmapU2S;
- outBytesLeft=0x80;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- iconv_close(cd);
- return -1;
- }
- } while (inBytesLeft > 0);
-
- myconv_rec[idx].srcSubS = 0x1A;
- myconv_rec[idx].srcSubD = 0xFFFD;
- myconv_rec[idx].subS = dmap_rec[idx].dmapU2S[0x1A];
-
- outBuf=(char *) &(myconv_rec[idx].subD);
- dmapSrc[0]=0xFFFD;
- inBuf=(char *) dmapSrc;
- inBytesLeft=2;
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "iconv(0x1A,1,%p,1) returns outBuf=%p, outBytesLeft=%d\n",
- dmapSrc, outBuf, outBytesLeft);
- }
-#endif
- if (outBytesLeft == 0) {
- /* UCS-2_IBM-eucKR returns error.
- myconv(iconv) rc=1, error=0, InBytesLeft=0, OutBytesLeft=18
- myconv(iconvRev) rc=-1, error=116, InBytesLeft=2, OutBytesLeft=20
- iconv: 0xFFFD => 0xAFFE => 0x rc=1,-1 sub=0,0
- */
- ;
- } else {
- iconv_close(cd);
- return -1;
- }
- }
-
- for (i = 0x80; i < 0xFFFF; ++i) {
- uchar eucBuf[3];
- dmapSrc[0]=i;
- inBuf=(char *) dmapSrc;
- inBytesLeft=2;
- outBuf=(char *) eucBuf;
- outBytesLeft=sizeof(eucBuf);
- errno=0;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (len == 1 && errno == 0 && inBytesLeft == 0 && outBytesLeft == 1) { /* substitution occurred. */ continue;
- }
-
- if (errno == EILSEQ) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft);
- if (inBuf - (char *) dmapSrc > 1 && inBuf - (char *) dmapSrc <= sizeof(dmapSrc) - 2)
- MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]);
- if (outBuf - (char *) dmap_rec[idx].dmapU2M2 > 1)
- MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- inBuf+=2;
- inBytesLeft-=2;
- memcpy(outBuf, (char *) &(myconv_rec[idx].subD), 2);
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc = %d, errno = %d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf[-2..0]=%02X%02X%02X, outBytesLeft=%d\n",
- i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1],
- inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft);
- MyPrintf(STDERR_WITH_TIME,
- "&dmapSrc=%p, inBuf=%p, dmapU2M2 + %d = %p, outBuf=%p\n",
- dmapSrc, inBuf, (i - 0x80) * 2, dmap_rec[idx].dmapU2M2 + (i - 0x80) * 2, outBuf);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- if (sizeof(eucBuf) - outBytesLeft == 1) {
- if (i < 0x100) {
- (dmap_rec[idx].dmapU2S)[i]=eucBuf[0];
- } else {
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2] = eucBuf[0];
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2 + 1] = 0x00;
- }
- } else if (sizeof(eucBuf) - outBytesLeft == 2) { /* 2 bytes */
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2] = eucBuf[0];
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2 + 1] = eucBuf[1];
- } else if (sizeof(eucBuf) - outBytesLeft == 3) { /* 3 byte SS2/SS3 */
- dmap_rec[idx].dmapU2M3[(i - 0x80) * 3] = eucBuf[0];
- dmap_rec[idx].dmapU2M3[(i - 0x80) * 3 + 1] = eucBuf[1];
- dmap_rec[idx].dmapU2M3[(i - 0x80) * 3 + 2] = eucBuf[2];
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf=%02X%02X%02X, outBytesLeft=%d\n",
- i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1],
- inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft);
- MyPrintf(STDERR_WITH_TIME,
- "&dmapSrc=%p, inBuf=%p, %p, outBuf=%p\n",
- dmapSrc, inBuf, dmap_rec[idx].dmapU2M3 + (i - 0x80) * 2, outBuf);
- }
-#endif
- return -1;
- }
-
- }
- iconv_close(cd);
- }
-
- } else if (myconvIsUTF16(from) && myconvIsUTF8(to)) {
- dmap_rec[idx].codingSchema = DMAP_T28;
-
- } else if (myconvIsUCS2(from) && myconvIsUTF8(to)) {
- dmap_rec[idx].codingSchema = DMAP_U28;
-
- } else if (myconvIsUTF8(from) && myconvIsUnicode2(to)) {
- dmap_rec[idx].codingSchema = DMAP_82U;
-
- } else if (myconvIsUnicode2(from) && myconvIsUnicode2(to)) {
- dmap_rec[idx].codingSchema = DMAP_U2U;
-
- } else {
-
- return -1;
- }
- myconv_rec[idx].cnv_dmap=&(dmap_rec[idx]);
- return 0;
-}
-
-
-
-static int bins_open(const char * to,
- const char * from,
- const int32_t idx)
-{
- return -1;
-}
-
-
-
-static int32_t dmap_close(const int32_t idx)
-{
- if (dmap_rec[idx].codingSchema == DMAP_S2S) {
- if (dmap_rec[idx].dmapS2S != NULL) {
- dmap_rec[idx].dmapS2S=NULL;
- }
- } else if (dmap_rec[idx].codingSchema = DMAP_E2U) {
- if (dmap_rec[idx].dmapE02U != NULL) {
- dmap_rec[idx].dmapE02U=NULL;
- }
- if (dmap_rec[idx].dmapE12U != NULL) {
- dmap_rec[idx].dmapE12U=NULL;
- }
- if (dmap_rec[idx].dmapE22U != NULL) {
- dmap_rec[idx].dmapE22U=NULL;
- }
- if (dmap_rec[idx].dmapE32U != NULL) {
- dmap_rec[idx].dmapE32U=NULL;
- }
- }
-
- return 0;
-}
-
-
-static int32_t bins_close(const int32_t idx)
-{
- return 0;
-}
-
-
-myconv_t myconv_open(const char * toCode,
- const char * fromCode,
- int32_t converter)
-{
- int32 i;
- for (i = 0; i < MAX_CONVERTER; ++i) {
- if (myconv_rec[i].converterType == 0)
- break;
- }
- if (i >= MAX_CONVERTER)
- return ((myconv_t) -1);
-
- myconv_rec[i].converterType = converter;
- myconv_rec[i].index=i;
- myconv_rec[i].fromCcsid=cstoccsid(fromCode);
- if (myconv_rec[i].fromCcsid == 0 && memcmp(fromCode, "big5",5) == 0)
- myconv_rec[i].fromCcsid=950;
- myconv_rec[i].toCcsid=cstoccsid(toCode);
- if (myconv_rec[i].toCcsid == 0 && memcmp(toCode, "big5",5) == 0)
- myconv_rec[i].toCcsid=950;
- strncpy(myconv_rec[i].from, fromCode, sizeof(myconv_rec[i].from)-1);
- strncpy(myconv_rec[i].to, toCode, sizeof(myconv_rec[i].to)-1);
-
- if (converter == CONVERTER_ICONV) {
- if ((myconv_rec[i].cnv_iconv=iconv_open(toCode, fromCode)) == (iconv_t) -1) {
- return ((myconv_t) -1);
- }
- myconv_rec[i].allocatedSize = -1;
- myconv_rec[i].srcSubS=myconvGetSubS(fromCode);
- myconv_rec[i].srcSubD=myconvGetSubD(fromCode);
- myconv_rec[i].subS=myconvGetSubS(toCode);
- myconv_rec[i].subD=myconvGetSubD(toCode);
- return &(myconv_rec[i]);
- } else if (converter == CONVERTER_DMAP &&
- dmap_open(toCode, fromCode, i) != -1) {
- return &(myconv_rec[i]);
- }
- return ((myconv_t) -1);
-}
-
-
-
-int32_t myconv_close(myconv_t cd)
-{
- int32_t ret=0;
-
- if (cd->converterType == CONVERTER_ICONV) {
- ret=iconv_close(cd->cnv_iconv);
- } else if (cd->converterType == CONVERTER_DMAP) {
- ret=dmap_close(cd->index);
- }
- memset(&(myconv_rec[cd->index]), 0x00, sizeof(myconv_rec[cd->index]));
- return ret;
-}
-
-
-
-
-/* reference: http://www-306.ibm.com/software/globalization/other/es.jsp */
-/* systemCL would be expensive, and myconvIsXXXXX is called frequently.
- need to cache entries */
-#define MAX_CCSID 256
-static int ccsidList [MAX_CCSID];
-static int esList [MAX_CCSID];
-int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme);
-EXTERN int myconvGetES(CCSID ccsid)
-{
- /* call QtqValidateCCSID in ILE to get encoding schema */
- /* return QtqValidateCCSID(ccsid); */
- int i;
- for (i = 0; i < MAX_CCSID; ++i) {
- if (ccsidList[i] == ccsid)
- return esList[i];
- if (ccsidList[i] == 0x00)
- break;
- }
-
- if (i >= MAX_CCSID) {
- i=MAX_CCSID-1;
- }
-
- {
- ccsidList[i]=ccsid;
- getEncodingScheme(ccsid, esList[i]);
-#ifdef DEBUG_PASE
- if (myconvDebug) {
- fprintf(stderr, "CCSID=%d, ES=0x%04X\n", ccsid, esList[i]);
- }
-#endif
- return esList[i];
- }
- return 0;
-}
-
-
-EXTERN int myconvIsEBCDIC(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x1100 ||
- es == 0x1200 ||
- es == 0x6100 ||
- es == 0x6200 ||
- es == 0x1301 ) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsISO(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x4100 ||
- es == 0x4105 ||
- es == 0x4155 ||
- es == 0x5100 ||
- es == 0x5150 ||
- es == 0x5200 ||
- es == 0x5404 ||
- es == 0x5409 ||
- es == 0x540A ||
- es == 0x5700) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsASCII(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x2100 ||
- es == 0x3100 ||
- es == 0x8100 ||
- es == 0x2200 ||
- es == 0x3200 ||
- es == 0x9200 ||
- es == 0x2300 ||
- es == 0x2305 ||
- es == 0x3300 ||
- es == 0x2900 ||
- es == 0x2A00) {
- return TRUE;
- } else if (memcmp(pName, "big5", 5) == 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-
-EXTERN int myconvIsUCS2(const char * pName)
-{
- if (cstoccsid(pName) == 13488) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUTF16(const char * pName)
-{
- if (cstoccsid(pName) == 1200) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUnicode2(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x7200 ||
- es == 0x720B ||
- es == 0x720F) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUTF8(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x7807) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUnicode(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x7200 ||
- es == 0x720B ||
- es == 0x720F ||
- es == 0x7807) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsEUC(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x4403) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsDBCS(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x1200 ||
- es == 0x2200 ||
- es == 0x2300 ||
- es == 0x2305 ||
- es == 0x2A00 ||
- es == 0x3200 ||
- es == 0x3300 ||
- es == 0x5200 ||
- es == 0x6200 ||
- es == 0x9200) {
- return TRUE;
- } else if (memcmp(pName, "big5", 5) == 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsSBCS(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x1100 ||
- es == 0x2100 ||
- es == 0x3100 ||
- es == 0x4100 ||
- es == 0x4105 ||
- es == 0x5100 ||
- es == 0x5150 ||
- es == 0x6100 ||
- es == 0x8100) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-
-EXTERN char myconvGetSubS(const char * code)
-{
- if (myconvIsEBCDIC(code)) {
- return 0x3F;
- } else if (myconvIsASCII(code)) {
- return 0x1A;
- } else if (myconvIsISO(code)) {
- return 0x1A;
- } else if (myconvIsEUC(code)) {
- return 0x1A;
- } else if (myconvIsUCS2(code)) {
- return 0x00;
- } else if (myconvIsUTF8(code)) {
- return 0x1A;
- }
- return 0x00;
-}
-
-
-EXTERN UniChar myconvGetSubD(const char * code)
-{
- if (myconvIsEBCDIC(code)) {
- return 0xFDFD;
- } else if (myconvIsASCII(code)) {
- return 0xFCFC;
- } else if (myconvIsISO(code)) {
- return 0x00;
- } else if (myconvIsEUC(code)) {
- return 0x00;
- } else if (myconvIsUCS2(code)) {
- return 0xFFFD;
- } else if (myconvIsUTF8(code)) {
- return 0x00;
- }
- return 0x00;
-}
-
diff --git a/storage/ibmdb2i/db2i_myconv.h b/storage/ibmdb2i/db2i_myconv.h
deleted file mode 100644
index 98032748148..00000000000
--- a/storage/ibmdb2i/db2i_myconv.h
+++ /dev/null
@@ -1,3201 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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.
-*/
-
-/**
- @file
-
- @brief A direct map optimization of iconv and related functions
- This was show to significantly reduce character conversion cost
- for short strings when compared to calling iconv system code.
-*/
-
-#ifndef DB2I_MYCONV_H
-#define DB2I_MYCONV_H
-
-
-#include <sys/time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <errno.h>
-#include <iconv.h>
-#include <ctype.h>
-#include <time.h>
-#include <stdarg.h>
-#include <string.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifdef __cplusplus
-#define INTERN inline
-#define EXTERN extern "C"
-#else
-#define INTERN static
-#define EXTERN extern
-#endif
-
-
-/* ANSI integer data types */
-#if defined(__OS400_TGTVRM__)
-/* for DTAMDL(*P128), datamodel(P128): int/long/pointer=4/4/16 */
-/* LLP64:4/4/8 is used for teraspace ?? */
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
-#elif defined(PASE)
-/* PASE uses IPL32: int/long/pointer=4/4/4 + long long */
-#elif defined(__64BIT__)
-/* AIX 64 bit uses LP64: int/long/pointer=4/8/8 */
-#endif
-
-#define CONVERTER_ICONV 1
-#define CONVERTER_DMAP 2
-
-#define DMAP_S2S 10
-#define DMAP_S2U 20
-#define DMAP_D2U 30
-#define DMAP_E2U 40
-#define DMAP_U2S 120
-#define DMAP_T2S 125
-#define DMAP_U2D 130
-#define DMAP_T2D 135
-#define DMAP_U2E 140
-#define DMAP_T2E 145
-#define DMAP_S28 220
-#define DMAP_D28 230
-#define DMAP_E28 240
-#define DMAP_82S 310
-#define DMAP_82D 320
-#define DMAP_82E 330
-#define DMAP_U28 410
-#define DMAP_82U 420
-#define DMAP_T28 425
-#define DMAP_U2U 510
-
-
-typedef struct __dmap_rec *dmap_t;
-
-struct __dmap_rec
-{
- uint32_t codingSchema;
- unsigned char * dmapS2S; /* SBCS -> SBCS */
- /* The following conversion needs be followed by conversion from UCS-2/UTF-16 to UTF-8 */
- UniChar * dmapD12U; /* DBCS(non-EUC) -> UCS-2/UTF-16 */
- UniChar * dmapD22U; /* DBCS(non-EUC) -> UCS-2/UTF-16 */
- UniChar * dmapE02U; /* EUC/SS0 -> UCS-2/UTF-16 */
- UniChar * dmapE12U; /* EUC/SS1 -> UCS-2/UTF-16 */
- UniChar * dmapE22U; /* EUC/0x8E + SS2 -> UCS-2/UTF-16 */
- UniChar * dmapE32U; /* EUC/0x8F + SS3 -> UCS-2/UTF-16 */
- uchar * dmapU2D; /* UCS-2 -> DBCS */
- uchar * dmapU2S; /* UCS-2 -> EUC SS0 */
- uchar * dmapU2M2; /* UCS-2 -> EUC SS1 */
- uchar * dmapU2M3; /* UCS-2 -> EUC SS2/SS3 */
- /* All of these pointers/tables are not used at the same time.
- * You may be able save some space if you consolidate them.
- */
- uchar * dmapS28; /* SBCS -> UTF-8 */
- uchar * dmapD28; /* DBCS -> UTF-8 */
-};
-
-typedef struct __myconv_rec *myconv_t;
-struct __myconv_rec
-{
- uint32_t converterType;
- uint32_t index; /* for close */
- union {
- iconv_t cnv_iconv;
- dmap_t cnv_dmap;
- };
- int32_t allocatedSize;
- int32_t fromCcsid;
- int32_t toCcsid;
- UniChar subD; /* DBCS substitution char */
- char subS; /* SBCS substitution char */
- UniChar srcSubD; /* DBCS substitution char of src codepage */
- char srcSubS; /* SBCS substitution char of src codepage */
- char from [41+1]; /* codepage name is up to 41 bytes */
- char to [41+1]; /* codepage name is up to 41 bytes */
-#ifdef __64BIT__
- char reserved[10]; /* align 128 */
-#else
- char reserved[14]; /* align 128 */
-#endif
-};
-
-
-EXTERN int32_t myconvDebug;
-
-
-
-EXTERN int myconvGetES(CCSID);
-EXTERN int myconvIsEBCDIC(const char *);
-EXTERN int myconvIsASCII(const char *);
-EXTERN int myconvIsUnicode(const char *); /* UTF-8, UTF-16, or UCS-2 */
-EXTERN int myconvIsUnicode2(const char *); /* 2 byte Unicode */
-EXTERN int myconvIsUCS2(const char *);
-EXTERN int myconvIsUTF16(const char *);
-EXTERN int myconvIsUTF8(const char *);
-EXTERN int myconvIsEUC(const char *);
-EXTERN int myconvIsISO(const char *);
-EXTERN int myconvIsSBCS(const char *);
-EXTERN int myconvIsDBCS(const char *);
-EXTERN char myconvGetSubS(const char *);
-EXTERN UniChar myconvGetSubD(const char *);
-
-
-EXTERN myconv_t myconv_open(const char*, const char*, int32_t);
-EXTERN int myconv_close(myconv_t);
-
-INTERN size_t myconv_iconv(myconv_t cd ,
- char** inBuf,
- size_t* inBytesLeft,
- char** outBuf,
- size_t* outBytesLeft,
- size_t* numSub)
-{
- return iconv(cd->cnv_iconv, inBuf, inBytesLeft, outBuf, outBytesLeft);
-}
-
-INTERN size_t myconv_dmap(myconv_t cd,
- char** inBuf,
- size_t* inBytesLeft,
- char** outBuf,
- size_t* outBytesLeft,
- size_t* numSub)
-{
- if (cd->cnv_dmap->codingSchema == DMAP_S2S) {
- register unsigned char * dmapS2S=cd->cnv_dmap->dmapS2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- } else {
- *pOut=dmapS2S[*pIn];
- if (*pOut == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(*inBytesLeft-inLen);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (*pOut == subS) {
- if ((*pOut=dmapS2S[*pIn]) == subS) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- }
- }
- ++pIn;
- --inLen;
- ++pOut;
- }
- *outBytesLeft-=(*inBytesLeft-inLen);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_E2U) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapE02U=(uchar *) (cd->cnv_dmap->dmapE02U);
- register uchar * dmapE12U=(uchar *) (cd->cnv_dmap->dmapE12U);
- register uchar * dmapE22U=(uchar *) (cd->cnv_dmap->dmapE22U);
- register uchar * dmapE32U=(uchar *) (cd->cnv_dmap->dmapE32U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- if (*pIn == 0x8E) { /* SS2 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722 || /* IBM-eucJP */
- cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) { /* 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- *pOut=dmapE22U[offset];
- ++pOut;
- *pOut=dmapE22U[offset+1];
- ++pOut;
- if (dmapE22U[offset] == 0xFF &&
- dmapE22U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 1 bytes */
- *pOut=dmapE22U[offset];
- ++pOut;
- *pOut=dmapE22U[offset+1];
- ++pOut;
- ++pIn;
- inLen-=2;
- }
- } else if (*pIn == 0x8F) { /* SS3 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722) /* IBM-eucJP */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 970 || /* IBM-eucKR */
- cd->fromCcsid == 964 || /* IBM-eucTW */
- cd->fromCcsid == 1383 || /* IBM-eucCN */
- (cd->fromCcsid == 33722 && 3 <= inLen)) /* IBM-eucJP */
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) { /* 0x8F + 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 33722)
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- *pOut=dmapE32U[offset];
- ++pOut;
- *pOut=dmapE32U[offset+1];
- ++pOut;
- if (dmapE32U[offset] == 0xFF &&
- dmapE32U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 0x8F + 1 bytes */
- *pOut=dmapE32U[offset];
- ++pOut;
- *pOut=dmapE32U[offset+1];
- ++pOut;
- ++pIn;
- inLen-=2;
- }
-
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x00) { /* SS1 */
- if (inLen < 2) {
- if ((cd->fromCcsid == 33722 && (*pIn == 0xA0 || (0xA9 <= *pIn && *pIn <= 0xAF) || *pIn == 0xFF)) ||
- (cd->fromCcsid == 970 && (*pIn == 0xA0 || *pIn == 0xAD || *pIn == 0xAE || *pIn == 0xAF || *pIn == 0xFF)) ||
- (cd->fromCcsid == 964 && (*pIn == 0xA0 || (0xAA <= *pIn && *pIn <= 0xC1) || *pIn == 0xC3 || *pIn == 0xFE || *pIn == 0xFF)) ||
- (cd->fromCcsid == 1383 && (*pIn == 0xA0 || *pIn == 0xFF)))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE12U[offset] == 0x00 &&
- dmapE12U[offset+1] == 0x00) { /* undefined mapping */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- *pOut=dmapE12U[offset];
- ++pOut;
- *pOut=dmapE12U[offset+1];
- ++pOut;
- if (dmapE12U[offset] == 0xFF &&
- dmapE12U[offset+1] == 0xFD) {
- if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else {
- *pOut=dmapE02U[offset];
- ++pOut;
- *pOut=dmapE02U[offset+1];
- ++pOut;
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_E28) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapE02U=(uchar *) (cd->cnv_dmap->dmapE02U);
- register uchar * dmapE12U=(uchar *) (cd->cnv_dmap->dmapE12U);
- register uchar * dmapE22U=(uchar *) (cd->cnv_dmap->dmapE22U);
- register uchar * dmapE32U=(uchar *) (cd->cnv_dmap->dmapE32U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- register UniChar in; /* copy part of U28 */
- register UniChar ucs2;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- if (*pIn == 0x8E) { /* SS2 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722 || /* IBM-eucJP */
- cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) { /* 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- in=dmapE22U[offset];
- in<<=8;
- in+=dmapE22U[offset+1];
- if (dmapE22U[offset] == 0xFF &&
- dmapE22U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 1 bytes */
- in=dmapE22U[offset];
- in<<=8;
- in+=dmapE22U[offset+1];
- ++pIn;
- inLen-=2;
- }
- } else if (*pIn == 0x8F) { /* SS3 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722) /* IBM-eucJP */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 970 || /* IBM-eucKR */
- cd->fromCcsid == 964 || /* IBM-eucTW */
- cd->fromCcsid == 1383 || /* IBM-eucCN */
- (cd->fromCcsid == 33722 && 3 <= inLen)) /* IBM-eucJP */
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) { /* 0x8F + 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 33722)
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- in=dmapE32U[offset];
- in<<=8;
- in+=dmapE32U[offset+1];
- if (dmapE32U[offset] == 0xFF &&
- dmapE32U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 0x8F + 1 bytes */
- in=dmapE32U[offset];
- in<<=8;
- in+=dmapE32U[offset+1];
- ++pIn;
- inLen-=2;
- }
-
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x00) { /* SS1 */
- if (inLen < 2) {
- if ((cd->fromCcsid == 33722 && (*pIn == 0xA0 || (0xA9 <= *pIn && *pIn <= 0xAF) || *pIn == 0xFF)) ||
- (cd->fromCcsid == 970 && (*pIn == 0xA0 || *pIn == 0xAD || *pIn == 0xAE || *pIn == 0xAF || *pIn == 0xFF)) ||
- (cd->fromCcsid == 964 && (*pIn == 0xA0 || (0xAA <= *pIn && *pIn <= 0xC1) || *pIn == 0xC3 || *pIn == 0xFE || *pIn == 0xFF)) ||
- (cd->fromCcsid == 1383 && (*pIn == 0xA0 || *pIn == 0xFF)))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE12U[offset] == 0x00 &&
- dmapE12U[offset+1] == 0x00) { /* undefined mapping */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- in=dmapE12U[offset];
- in<<=8;
- in+=dmapE12U[offset+1];
- if (dmapE12U[offset] == 0xFF &&
- dmapE12U[offset+1] == 0xFD) {
- if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else {
- in=dmapE02U[offset];
- in<<=8;
- in+=dmapE02U[offset+1];
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- }
- ucs2=in;
- if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) {
- *pOut=0xEF;
- ++pOut;
- *pOut=0xBF;
- ++pOut;
- *pOut=0xBD;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte<<=2;
- work=ucs2; /* dmapD12U[offset+1]; */
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- /* end of U28 */
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2E) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2;
- register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- register size_t rc=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (in < 0x100 && dmapU2S[in] != 0x0000) {
- if ((*pOut=dmapU2S[in]) == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pOut;
- } else {
- in<<=1;
- if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */
- in*=1.5;
- if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/
- *pOut=pSubD[0];
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- ++rc;
- } else {
- *pOut=dmapU2M3[in];
- ++pOut;
- *pOut=dmapU2M3[1+in];
- ++pOut;
- *pOut=dmapU2M3[2+in];
- ++pOut;
- }
- } else {
- *pOut=dmapU2M2[in];
- ++pOut;
- if (dmapU2M2[1+in] == 0x00) {
- if (*pOut == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2M2[1+in];
- ++pOut;
- if (memcmp(pOut-2, pSubD, 2) == 0) {
- in>>=1;
- if (in != cd->srcSubD) {
- ++numS;
- ++rc;
- }
- }
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return rc; /* compatibility to iconv() */
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T2E) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2;
- register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- register size_t rc=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen-1;
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (0xD800 <= in && in <= 0xDBFF) { /* first byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else if (0xDC00 <= in && in <= 0xDFFF) { /* second byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else if (in < 0x100 && dmapU2S[in] != 0x0000) {
- if ((*pOut=dmapU2S[in]) == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pOut;
- } else {
- in<<=1;
- if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */
- in*=1.5;
- if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/
- *pOut=pSubD[0];
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- ++rc;
- } else {
- *pOut=dmapU2M3[in];
- ++pOut;
- *pOut=dmapU2M3[1+in];
- ++pOut;
- *pOut=dmapU2M3[2+in];
- ++pOut;
- }
- } else {
- *pOut=dmapU2M2[in];
- ++pOut;
- if (dmapU2M2[1+in] == 0x00) {
- if (*pOut == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2M2[1+in];
- ++pOut;
- if (memcmp(pOut-2, pSubD, 2) == 0) {
- in>>=1;
- if (in != cd->srcSubD) {
- ++numS;
- ++rc;
- }
- }
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82E) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2;
- register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- register size_t rc=0;
- while (0 < inLen) {
- register uint32_t in;
- uint32_t in2;
- if (pLastOutBuf < pOut)
- break;
- /* convert from UTF-8 to UCS-2 */
- if (*pIn == 0x00) {
- in=0x0000;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- in=byte1;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- in=byte1;
- in<<=8;
- in+=byte2;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- in=byte1 | byte2;;
- in<<=8;
- in+=byte3;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4)) { /* (bytes1 & 11111000) == 0x1110000 */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- /* iconv() returns 0 for 0xF4908080 and convert to 0x00
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- */
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- in=work;
- in<<=8;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- in+=work;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- in2=work;
- in2<<=8;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- in2+=byte4;
- inLen-=4;
- ++pIn;
-#ifdef match_with_GBK
- if ((0xD800 == in && in2 < 0xDC80) ||
- (0xD840 == in && in2 < 0xDC80) ||
- (0xD880 == in && in2 < 0xDC80) ||
- (0xD8C0 == in && in2 < 0xDC80) ||
- (0xD900 == in && in2 < 0xDC80) ||
- (0xD940 == in && in2 < 0xDC80) ||
- (0xD980 == in && in2 < 0xDC80) ||
- (0xD9C0 == in && in2 < 0xDC80) ||
- (0xDA00 == in && in2 < 0xDC80) ||
- (0xDA40 == in && in2 < 0xDC80) ||
- (0xDA80 == in && in2 < 0xDC80) ||
- (0xDAC0 == in && in2 < 0xDC80) ||
- (0xDB00 == in && in2 < 0xDC80) ||
- (0xDB40 == in && in2 < 0xDC80) ||
- (0xDB80 == in && in2 < 0xDC80) ||
- (0xDBC0 == in && in2 < 0xDC80)) {
-#else
- if ((0xD800 <= in && in <= 0xDBFF) &&
- (0xDC00 <= in2 && in2 <= 0xDFFF)) {
-#endif
- *pOut=subS;
- ++pOut;
- ++numS;
- continue;
- }
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if (0xF5 <= byte1 && byte1 <= 0xFF) { /* minic iconv() behavior */
- if (inLen < 4 ||
- (inLen >= 4 && byte1 == 0xF8 && pIn[1] < 0x90) ||
- pIn[1] < 0x80 || 0xBF < pIn[1] ||
- pIn[2] < 0x80 || 0xBF < pIn[2] ||
- pIn[3] < 0x80 || 0xBF < pIn[3] ) {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && (byte1 == 0xF8 || (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
-
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- } else if ((pIn[1] == 0x80 || pIn[1] == 0x90 || pIn[1] == 0xA0 || pIn[1] == 0xB0) &&
- pIn[2] < 0x82) {
- *pOut=subS; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- } else {
- *pOut=pSubD[0]; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- /* iconv() returns 0 with strange 1 byte converted values */
- }
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- /* end of UTF-8 to UCS-2 */
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (in < 0x100 && dmapU2S[in] != 0x0000) {
- if ((*pOut=dmapU2S[in]) == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pOut;
- } else {
- in<<=1;
- if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */
- in*=1.5;
- if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/
- *pOut=pSubD[0];
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- ++rc;
- } else {
- *pOut=dmapU2M3[in];
- ++pOut;
- *pOut=dmapU2M3[1+in];
- ++pOut;
- *pOut=dmapU2M3[2+in];
- ++pOut;
- }
- } else {
- *pOut=dmapU2M2[in];
- ++pOut;
- if (dmapU2M2[1+in] == 0x00) {
- if (*pOut == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2M2[1+in];
- ++pOut;
- if (memcmp(pOut-2, pSubD, 2) == 0) {
- in>>=1;
- if (in != cd->srcSubD) {
- ++numS;
- ++rc;
- }
- }
- }
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_S2U) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- *pOut=dmapD12U[offset];
- ++pOut;
- *pOut=dmapD12U[offset+1];
- ++pOut;
- if (dmapD12U[offset] == 0x00) {
- if (dmapD12U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- } else if (dmapD12U[offset+1] == 0x00) {
- pOut-=2;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- ++pIn;
- --inLen;
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_S28) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- register UniChar in; /* copy part of U28 */
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- in=dmapD12U[offset];
- in<<=8;
- in+=dmapD12U[offset+1];
- if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- if (in == 0x000) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=dmapD12U[offset+1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) { /* There should not be no surrogate character in SBCS. */
- *pOut=0xEF;
- ++pOut;
- *pOut=0xBF;
- ++pOut;
- *pOut=0xBD;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=dmapD12U[offset];
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=dmapD12U[offset];
- byte<<=2;
- work=dmapD12U[offset+1];
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=dmapD12U[offset+1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- /* end of U28 */
- if (dmapD12U[offset] == 0x00) {
- if (dmapD12U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- }
- ++pIn;
- --inLen;
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2S) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
-
- *inBytesLeft=inLen;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- } else {
- if ((*pOut=dmapU2S[in]) == 0x00) {
- *pOut=subS;
- ++numS;
- errno=EINVAL; /* 22 */
- } else if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- }
- ++pOut;
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return numS;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T2S) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
-
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
-
- } else if (0xD800 <= in && in <= 0xDFFF) { /* 0xD800-0xDFFF, surrogate first and second values */
- if (0xDC00 <= in ) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
-
- } else if (inLen < 4) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- return -1;
-
- } else {
- register uint32_t in2;
- in2=pIn[2];
- in2<<=8;
- in2+=pIn[3];
- if (0xDC00 <= in2 && in2 <= 0xDFFF) { /* second surrogate character =0xDC00 - 0xDFFF*/
- *pOut=subS;
- ++numS;
- pIn+=4;
- } else {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- }
- } else {
- if ((*pOut=dmapU2S[in]) == 0x00) {
- *pOut=subS;
- ++numS;
- errno=EINVAL; /* 22 */
- } else if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- }
- ++pOut;
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82S) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- uint32_t in2; /* The second surrogate value */
- if (pLastOutBuf < pOut)
- break;
- /* convert from UTF-8 to UCS-2 */
- if (*pIn == 0x00) {
- in=0x0000;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- in=byte1;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- in=byte1;
- in<<=8;
- in+=byte2;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- in=byte1 | byte2;;
- in<<=8;
- in+=byte3;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4) || /* (bytes1 & 11111000) == 0x1110000 */
- ((byte1&=0xF7) && 0xF0 <= byte1 && byte1 <= 0xF4)) { /* minic iconv() behavior */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- /* iconv() returns 0 for 0xF4908080 and convert to 0x00
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- */
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- in=work;
- in<<=8;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- in+=work;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- in2=work;
- in2<<=8;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- in2+=byte4;
- inLen-=4;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xF0) { /* minic iconv() behavior */
- if (inLen < 4 ||
- pIn[1] < 0x80 || 0xBF < pIn[1] ||
- pIn[2] < 0x80 || 0xBF < pIn[2] ||
- pIn[3] < 0x80 || 0xBF < pIn[3] ) {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
-
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- } else {
- *pOut=subS; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- /* UTF-8_IBM-850 0xF0908080 : converted value does not match, iconv=0x00, dmap=0x7F
- UTF-8_IBM-850 0xF0908081 : converted value does not match, iconv=0x01, dmap=0x7F
- UTF-8_IBM-850 0xF0908082 : converted value does not match, iconv=0x02, dmap=0x7F
- UTF-8_IBM-850 0xF0908083 : converted value does not match, iconv=0x03, dmap=0x7F
- ....
- UTF-8_IBM-850 0xF09081BE : converted value does not match, iconv=0x7E, dmap=0x7F
- UTF-8_IBM-850 0xF09081BF : converted value does not match, iconv=0x1C, dmap=0x7F
- UTF-8_IBM-850 0xF09082A0 : converted value does not match, iconv=0xFF, dmap=0x7F
- UTF-8_IBM-850 0xF09082A1 : converted value does not match, iconv=0xAD, dmap=0x7F
- ....
- */
- continue;
- /* iconv() returns 0 with strange 1 byte converted values */
- }
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- /* end of UTF-8 to UCS-2 */
- if (in == 0x0000) {
- *pOut=0x00;
- } else {
- if ((*pOut=dmapU2S[in]) == 0x00) {
- *pOut=subS;
- ++numS;
- errno=EINVAL; /* 22 */
- } else if (*pOut == subS) {
- if (in != cd->srcSubS) {
- ++numS;
- }
- }
- }
- ++pOut;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_D2U) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register uchar * dmapD22U=(uchar *) (cd->cnv_dmap->dmapD22U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x00) { /* DBCS */
- if (inLen < 2) {
- if (*pIn == 0x80 || *pIn == 0xFF ||
- (cd->fromCcsid == 943 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0xA0 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xEF || *pIn == 0xFD || *pIn == 0xFE)) ||
- (cd->fromCcsid == 932 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0x87 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xED || *pIn == 0xEE || *pIn == 0xEF)) ||
- (cd->fromCcsid == 1381 && ((0x85 <= *pIn && *pIn <= 0x8B) || (0xAA <= *pIn && *pIn <= 0xAF) || (0xF8 <= *pIn && *pIn <= 0xFE))))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset-=0x100;
- ++pIn;
- offset<<=8;
- offset+=(*pIn * 2);
- if (dmapD22U[offset] == 0x00 &&
- dmapD22U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- *pOut=dmapD22U[offset];
- ++pOut;
- *pOut=dmapD22U[offset+1];
- ++pOut;
- if (dmapD22U[offset] == 0xFF &&
- dmapD22U[offset+1] == 0xFD) {
- if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else { /* SBCS */
- *pOut=dmapD12U[offset];
- ++pOut;
- *pOut=dmapD12U[offset+1];
- ++pOut;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_D28) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register uchar * dmapD22U=(uchar *) (cd->cnv_dmap->dmapD22U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- register UniChar in; /* copy part of U28 */
- register UniChar ucs2;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x00) { /* DBCS */
- if (inLen < 2) {
- if (*pIn == 0x80 || *pIn == 0xFF ||
- (cd->fromCcsid == 943 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0xA0 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xEF || *pIn == 0xFD || *pIn == 0xFE)) ||
- (cd->fromCcsid == 932 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0x87 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xED || *pIn == 0xEE || *pIn == 0xEF)) ||
- (cd->fromCcsid == 1381 && ((0x85 <= *pIn && *pIn <= 0x8B) || (0xAA <= *pIn && *pIn <= 0xAF) || (0xF8 <= *pIn && *pIn <= 0xFE))))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset-=0x100;
- ++pIn;
- offset<<=8;
- offset+=(*pIn * 2);
- if (dmapD22U[offset] == 0x00 &&
- dmapD22U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- in=dmapD22U[offset];
- in<<=8;
- in+=dmapD22U[offset+1];
- ucs2=in;
- if (dmapD22U[offset] == 0xFF &&
- dmapD22U[offset+1] == 0xFD) {
- if (in != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else { /* SBCS */
- in=dmapD12U[offset];
- in<<=8;
- in+=dmapD12U[offset+1];
- ucs2=in;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x1A) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) { /* There should not be no surrogate character in SBCS. */
- *pOut=0xEF;
- ++pOut;
- *pOut=0xBF;
- ++pOut;
- *pOut=0xBD;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte<<=2;
- work=ucs2; /* dmapD12U[offset+1]; */
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- /* end of U28 */
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2D) {
- register uchar * dmapU2D=cd->cnv_dmap->dmapU2D;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
-
- *inBytesLeft=inLen;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else {
- in<<=1;
- *pOut=dmapU2D[in];
- ++pOut;
- if (dmapU2D[in+1] == 0x00) { /* SBCS */
- if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2D[in+1];
- ++pOut;
- if (dmapU2D[in] == pSubD[0] &&
- dmapU2D[in+1] == pSubD[1]) {
- in>>=1;
- if (in != cd->srcSubD)
- ++numS;
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return numS; /* to minic iconv() behavior */
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T2D) {
- register uchar * dmapU2D=cd->cnv_dmap->dmapU2D;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (0xD800 <= in && in <= 0xDBFF) { /* first byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else if (0xDC00 <= in && in <= 0xDFFF) { /* second byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else {
- in<<=1;
- *pOut=dmapU2D[in];
- ++pOut;
- if (dmapU2D[in+1] == 0x00) { /* SBCS */
- if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2D[in+1];
- ++pOut;
- if (dmapU2D[in] == pSubD[0] &&
- dmapU2D[in+1] == pSubD[1]) {
- in>>=1;
- if (in != cd->srcSubD)
- ++numS;
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0; /* to minic iconv() behavior */
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82D) {
- register uchar * dmapU2D=cd->cnv_dmap->dmapU2D;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- uint32_t in2;
- if (pLastOutBuf < pOut)
- break;
- /* convert from UTF-8 to UCS-2 */
- if (*pIn == 0x00) {
- in=0x0000;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- in=byte1;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- in=byte1;
- in<<=8;
- in+=byte2;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- in=byte1 | byte2;;
- in<<=8;
- in+=byte3;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4)) { /* (bytes1 & 11111000) == 0x1110000 */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- /* iconv() returns 0 for 0xF4908080 and convert to 0x00
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- */
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- in=work;
- in<<=8;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- in+=work;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- in2=work;
- in2<<=8;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- in2+=byte4;
- inLen-=4;
- ++pIn;
-#ifdef match_with_GBK
- if ((0xD800 == in && in2 < 0xDC80) ||
- (0xD840 == in && in2 < 0xDC80) ||
- (0xD880 == in && in2 < 0xDC80) ||
- (0xD8C0 == in && in2 < 0xDC80) ||
- (0xD900 == in && in2 < 0xDC80) ||
- (0xD940 == in && in2 < 0xDC80) ||
- (0xD980 == in && in2 < 0xDC80) ||
- (0xD9C0 == in && in2 < 0xDC80) ||
- (0xDA00 == in && in2 < 0xDC80) ||
- (0xDA40 == in && in2 < 0xDC80) ||
- (0xDA80 == in && in2 < 0xDC80) ||
- (0xDAC0 == in && in2 < 0xDC80) ||
- (0xDB00 == in && in2 < 0xDC80) ||
- (0xDB40 == in && in2 < 0xDC80) ||
- (0xDB80 == in && in2 < 0xDC80) ||
- (0xDBC0 == in && in2 < 0xDC80)) {
-#else
- if ((0xD800 <= in && in <= 0xDBFF) &&
- (0xDC00 <= in2 && in2 <= 0xDFFF)) {
-#endif
- *pOut=subS;
- ++pOut;
- ++numS;
- continue;
- }
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if (0xF5 <= byte1 && byte1 <= 0xFF) { /* minic iconv() behavior */
- if (inLen < 4 ||
- (inLen >= 4 && byte1 == 0xF8 && pIn[1] < 0x90) ||
- pIn[1] < 0x80 || 0xBF < pIn[1] ||
- pIn[2] < 0x80 || 0xBF < pIn[2] ||
- pIn[3] < 0x80 || 0xBF < pIn[3] ) {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && (byte1 == 0xF8 || (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
-
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- } else if ((pIn[1] == 0x80 || pIn[1] == 0x90 || pIn[1] == 0xA0 || pIn[1] == 0xB0) &&
- pIn[2] < 0x82) {
- *pOut=subS; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- } else {
- *pOut=pSubD[0]; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- /* iconv() returns 0 with strange 1 byte converted values */
- }
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- /* end of UTF-8 to UCS-2 */
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else {
- in<<=1;
- *pOut=dmapU2D[in];
- ++pOut;
- if (dmapU2D[in+1] == 0x00) { /* SBCS */
- if (dmapU2D[in] == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2D[in+1];
- ++pOut;
- if (dmapU2D[in] == pSubD[0] &&
- dmapU2D[in+1] == pSubD[1]) {
- in>>=1;
- if (in != cd->srcSubD)
- ++numS;
- }
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82U) {
- /* See http://unicode.org/versions/corrigendum1.html */
- /* convert from UTF-8 to UTF-16 can cover all conversion from UTF-8 to UCS-2 */
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- *pOut=0x00;
- ++pOut;
- *pOut=byte1;
- ++pOut;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- *pOut=byte1;
- ++pOut;
- *pOut=byte2;
- ++pOut;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- *pOut=byte1 | byte2;;
- ++pOut;
- *pOut=byte3;
- ++pOut;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4) || /* (bytes1 & 11111000) == 0x1110000 */
- ((byte1&=0xF7) && 0xF0 <= byte1 && byte1 <= 0xF4)) { /* minic iconv() behavior */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4 || cd->toCcsid == 13488) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- *pOut=work;
- ++pOut;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- *pOut=work;
- ++pOut;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- *pOut=work;
- ++pOut;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- *pOut=byte4;
- ++pOut;
- inLen-=4;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xF0) {
- if (cd->toCcsid == 13488) {
- errno=EILSEQ; /* 116 */
- } else {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
- } else if (cd->cnv_dmap->codingSchema == DMAP_U28) {
- /* See http://unicode.org/versions/corrigendum1.html */
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- // register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=pIn[0];
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[0];
- byte<<=2;
- work=pIn[1];
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- // *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T28) { /* UTF-16_UTF-8 */
- /* See http://unicode.org/versions/corrigendum1.html */
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- // register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=0;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) { /* in & 0b1111110000000000 == 0b1101100000000000, first surrogate character */
- if (0xDC00 <= in ) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
-
- } else if (inLen < 4) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- return -1;
-
- } else if ((pIn[2] & 0xFC) != 0xDC) { /* pIn[2] & 0b11111100 == 0b11011100, second surrogate character */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- return -1;
-
- } else {
- register uchar byte;
- register uchar work;
- in>>=6;
- in&=0x000F; /* 0b0000000000001111 */
- byte=in; /* wwww */
- ++byte; /* uuuuu */
- work=byte; /* save uuuuu */
- byte>>=2;
- byte|=0xF0; /* 0b11110000; */
- *pOut=byte;
- ++pOut;
-
- byte=work;
- byte&=0x03; /* 0b00000011; */
- byte<<=4;
- byte|=0x80; /* 0b10000000; */
- work=pIn[1];
- work&=0x3C; /* 0b00111100; */
- work>>=2;
- byte|=work;
- *pOut=byte;
- ++pOut;
-
- byte=pIn[1];
- byte&=0x03; /* 0b00000011; */
- byte<<=4;
- byte|=0x80; /* 0b10000000; */
- work=pIn[2];
- work&=0x03; /* 0b00000011; */
- work<<=2;
- byte|=work;
- work=pIn[3];
- work>>=6;
- byte|=work;
- *pOut=byte;
- ++pOut;
-
- byte=pIn[3];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- pIn+=2;
- inLen-=2;
- }
- } else if ((in & 0xFC00) == 0xDC00) { /* in & 0b11111100 == 0b11011100, second surrogate character */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
-
- } else {
- register uchar byte;
- register uchar work;
- byte=pIn[0];
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[0];
- byte<<=2;
- work=pIn[1];
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- // *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2U) { /* UTF-16_UCS-2 */
- register int inLen=*inBytesLeft;
- register int outLen=*outBytesLeft;
- if (inLen <= outLen) {
- memcpy(*outBuf, *inBuf, inLen);
- (*outBytesLeft)-=inLen;
- (*inBuf)+=inLen;
- (*outBuf)+=inLen;
- *inBytesLeft=0;
- return 0;
- }
- memcpy(*outBuf, *inBuf, outLen);
- (*outBytesLeft)=0;
- (*inBuf)+=outLen;
- (*outBuf)+=outLen;
- *inBytesLeft-=outLen;
- return (*inBytesLeft);
-
- } else {
- return -1;
- }
- return 0;
-}
-
-
-#ifdef DEBUG
-inline size_t myconv(myconv_t cd ,
- char** inBuf,
- size_t* inBytesLeft,
- char** outBuf,
- size_t* outBytesLeft,
- size_t* numSub)
-{
- if (cd->converterType == CONVERTER_ICONV) {
- return myconv_iconv(cd,inBuf,inBytesLeft,outBuf,outBytesLeft,numSub);
- } else if (cd->converterType == CONVERTER_DMAP) {
- return myconv_dmap(cd,inBuf,inBytesLeft,outBuf,outBytesLeft,numSub);
- }
- return -1;
-}
-
-inline char * converterName(int32_t type)
-{
- if (type == CONVERTER_ICONV)
- return "iconv";
- else if (type == CONVERTER_DMAP)
- return "dmap";
-
- return "?????";
-}
-#else
-#define myconv(a,b,c,d,e,f) \
-(((a)->converterType == CONVERTER_ICONV)? myconv_iconv((a),(b),(c),(d),(e),(f)): (((a)->converterType == CONVERTER_DMAP)? myconv_dmap((a),(b),(c),(d),(e),(f)): -1))
-
-
-#define converterName(a) \
-(((a) == CONVERTER_ICONV)? "iconv": ((a) == CONVERTER_DMAP)? "dmap": "?????")
-#endif
-
-void initMyconv();
-void cleanupMyconv();
-
-#endif
diff --git a/storage/ibmdb2i/db2i_rir.cc b/storage/ibmdb2i/db2i_rir.cc
deleted file mode 100644
index 091c4d98383..00000000000
--- a/storage/ibmdb2i/db2i_rir.cc
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "ha_ibmdb2i.h"
-
-/* Helper function for records_in_range.
- Input: Bitmap of used key parts.
- Output: Number of used key parts. */
-
-static inline int getKeyCntFromMap(key_part_map keypart_map)
-{
- int cnt = 0;
- while (keypart_map)
- {
- keypart_map = keypart_map >> 1;
- cnt++;
- }
- return (cnt);
-}
-
-/**
- @brief
- Given a starting key and an ending key, estimate the number of rows that
- will exist between the two keys.
-
- INPUT
- inx Index to use
- min_key Min key. Is NULL if no min range
- max_key Max key. Is NULL if no max range
-
- NOTES
- min_key.flag can have one of the following values:
- HA_READ_KEY_EXACT Include the key in the range
- HA_READ_AFTER_KEY Don't include key in range
-
- max_key.flag can have one of the following values:
- HA_READ_BEFORE_KEY Don't include key in range
- HA_READ_AFTER_KEY Include all 'end_key' values in the range
-
- RETURN
- HA_POS_ERROR Error or the storage engine cannot estimate the number of rows
- 1 There are no matching keys in the given range
- n > 0 There are approximately n rows in the range
-*/
-ha_rows ha_ibmdb2i::records_in_range(uint inx,
- key_range *min_key,
- key_range *max_key)
-{
- DBUG_ENTER("ha_ibmdb2i::records_in_range");
- int rc = 0; // Return code
- ha_rows rows = 0; // Row count returned to caller of this method
- uint32 spcLen; // Length of space passed to DB2
- uint32 keyCnt; // Number of fields in the key composite
- uint32 literalCnt = 0; // Number of literals
- uint32 boundsOff; // Offset from beginning of space to range bounds
- uint32 litDefOff; // Offset from beginning of space to literal definitions
- uint32 literalsOff; // Offset from beginning of space to literal values
- uint32 cutoff = 0; // Early exit cutoff (currently not used)
- uint64 recCnt; // Row count from DB2
- uint16 rtnCode; // Return code from DB2
- Bounds* boundsPtr; // Pointer to a pair of range bounds
- Bound* boundPtr; // Pointer to a single (high or low) range bound
- LitDef* litDefPtr; // Pointer to a literal definition
- char* literalsPtr; // Pointer to the start of all literal values
- char* literalPtr; // Pointer to the start of this literal value
- char* tempPtr; // Temporary pointer
- char* tempMinPtr; // Temporary pointer into min_key
- int minKeyCnt = 0; // Number of fields in the min_key composite
- int maxKeyCnt = 0; // Number of fields in the max_key composite
- size_t tempLen = 0; // Temporary length
- uint16 DB2FieldWidth = 0; // DB2 field width
- uint32 workFieldLen = 0; // Length of workarea needed for CCSID conversions
- bool overrideInclusion; // Indicator for inclusion/exclusion
- char* endOfLiteralPtr; // Pointer to the end of this literal
- char* endOfMinPtr; // Pointer to end of min_key
- uint16 endByte = 0; // End byte of char or graphic literal (padding not included)
- bool reuseLiteral; // Indicator that hi and lo bounds use same literal
- char* minPtr = NULL; // Work pointer for traversing min_key
- char* maxPtr = NULL; // Work pointer for traversing max_key
- /*
- Handle the special case of 'x < null' anywhere in the key range. There are
- no values less than null, but return 1 so that MySQL does not assume
- the empty set for the query.
- */
- if (min_key != NULL && max_key != NULL &&
- min_key->flag == HA_READ_AFTER_KEY && max_key->flag == HA_READ_BEFORE_KEY &&
- min_key->length == max_key->length &&
- (memcmp((uchar*)min_key->key,(uchar*)max_key->key,min_key->length)==0))
- {
- DBUG_PRINT("ha_ibmdb2i::records_in_range",("Estimate 1 row for key %d; special case: < null", inx));
- DBUG_RETURN((ha_rows) 1 );
- }
- /*
- Determine the number of fields in the key composite.
- */
-
- if (min_key)
- {
- minKeyCnt = getKeyCntFromMap(min_key->keypart_map);
- minPtr = (char*)min_key->key;
- }
- if (max_key)
- {
- maxKeyCnt = getKeyCntFromMap(max_key->keypart_map);
- maxPtr = (char*)max_key->key;
- }
- keyCnt = maxKeyCnt >= minKeyCnt ? maxKeyCnt : minKeyCnt;
-
- /*
- Handle the special case where MySQL does not pass either a min or max
- key range. In this case, set the key count to 1 (knowing that there
- is at least one key field) to flow through and create one bounds structure.
- When both the min and max key ranges are nil, the bounds structure will
- specify positive and negative infinity and DB2 will estimate the total
- number of rows. */
-
- if (keyCnt == 0)
- keyCnt = 1;
-
- /*
- Allocate the space needed to pass range information to DB2. The
- space must be large enough to store the following:
- - one pair of bounds (high and low) per field in the key composite
- - one literal definition per literal value
- - the literal values
- - work area for literal CCSID conversions
- Since we don't know yet how many of these structures are needed,
- allocate enough space for the maximum that we will possibly need.
- The workarea for the literal conversion must be big enough to hold the
- largest of the DB2 key fields.
- */
- KEY& curKey = table->key_info[inx];
-
- for (int i = 0; i < keyCnt; i++)
- {
- DB2FieldWidth =
- db2Table->db2Field(curKey.key_part[i].field->field_index).getByteLengthInRecord();
- if (DB2FieldWidth > workFieldLen)
- workFieldLen = DB2FieldWidth; // Get length of largest DB2 field
- tempLen = tempLen + DB2FieldWidth; // Tally the DB2 field lengths
- }
- spcLen = (sizeof(Bounds)*keyCnt) + (sizeof(LitDef)*keyCnt*2) + (tempLen*2) + workFieldLen;
-
- ValidatedPointer<char> spcPtr(spcLen); // Pointer to space passed to DB2
- memset(spcPtr, 0, spcLen); // Clear the allocated space
- /*
- Set addressability to the various sections of the DB2 interface space.
- */
- boundsOff = 0; // Range bounds are at the start of the space
- litDefOff = sizeof(Bounds) * keyCnt; // Literal defs follow all the range bounds
- literalsOff = litDefOff + (sizeof(LitDef) * keyCnt * 2); // Literal values are last
- boundsPtr = (Bounds_t*)(void*)spcPtr; // Address first bounds structure
- tempPtr = (char*)((char*)spcPtr + litDefOff);
- litDefPtr = (LitDef_t*)tempPtr; // Address first literal definition
- tempPtr = (char*)((char*)spcPtr + literalsOff);
- literalsPtr = (char*)tempPtr; // Address start of literal values
- literalPtr = literalsPtr; // Address first literal value
- /*
- For each key part, build the low (min) and high (max) DB2 range bounds.
- If literals are specified in the MySQL range, build DB2 literal
- definitions and store the literal values for access by DB2.
-
- If no value is specified for a key part, assume infinity. Negative
- infinity will cause processing to start at the first index entry.
- Positive infinity will cause processing to end at the last index entry.
- When infinity is specified in a bound, inclusion/exclusion and position
- are ignored, and there is no literal definition or literal value for
- the bound.
-
- If the keypart value is null, the null indicator is set in the range
- bound and the other fields in the bound are ignored. When the bound is
- null, only index entries with the null value will be included in the
- estimate. If one bound is null, both bounds must be null. When the bound
- is not null, the data offset and length must be set, and the literal
- value stored for access by DB2.
- */
- for (int partsInUse = 0; partsInUse < keyCnt; ++partsInUse)
- {
- Field *field= curKey.key_part[partsInUse].field;
- overrideInclusion = false;
- reuseLiteral = false;
- endOfLiteralPtr = NULL;
- /*
- Build the low bound for the key range.
- */
- if ((partsInUse + 1) > minKeyCnt) // if no min_key info for this part
- boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where 3 between x and y
- else
- {
- if ((curKey.key_part[partsInUse].null_bit) && (char*)minPtr[0])
- { // min_key is null
- if (max_key == NULL ||
- ((partsInUse + 1) > maxKeyCnt)) // select...where x='ab' and y=null and z != 'c'
- boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where x not null or
- // select...where x > null
- else // max_key is not null
- {
- if (min_key->flag == HA_READ_KEY_EXACT)
- boundsPtr->LoBound.IsNull[0] = QMY_YES; // select...where x is null
- else
- {
- if ((char*)maxPtr[0])
- boundsPtr->LoBound.IsNull[0] = QMY_YES; // select...where a = null and b < 5 (max-before)
- // select...where a='a' and b is null and c !='a' (max-after)
- else
- boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where x < y
- }
- } // end min_key is null
- }
- else // min_key is not null
- {
- if (literalCnt) litDefPtr = litDefPtr + 1;
- literalCnt = literalCnt + 1;
- boundsPtr->LoBound.Position = literalCnt;
- /*
- Determine inclusion or exclusion.
- */
- if (min_key->flag == HA_READ_KEY_EXACT || //select...where a like 'this%'
-
- /* An example for the following conditions is 'select...where a = 5 and b > null'. */
-
- (max_key &&
- (memcmp((uchar*)minPtr,(uchar*)maxPtr,
- curKey.key_part[partsInUse].store_length)==0)))
-
- {
- if ((min_key->flag != HA_READ_KEY_EXACT) ||
- (max_key &&
- (memcmp((uchar*)minPtr,(uchar*)maxPtr,
- curKey.key_part[partsInUse].store_length)==0)))
- overrideInclusion = true; // Need inclusion for both min and max
- }
- else
- boundsPtr->LoBound.Embodiment[0] = QMY_EXCLUSION;
- litDefPtr->FieldNbr = field->field_index + 1;
- DB2Field& db2Field = db2Table->db2Field(field->field_index);
- litDefPtr->DataType = db2Field.getType();
- /*
- Convert the literal to DB2 format
- */
- if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data
- (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data
- (litDefPtr->DataType == QMY_CHAR ||
- litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_GRAPHIC ||
- litDefPtr->DataType == QMY_VARGRAPHIC))
- {
- // Most of the code is required by the considerable wrangling needed
- // to prepare partial keys for use by DB2
- // 1. UTF8 (CCSID 1208) data can be copied across unmodified if it is
- // utf8_bin. Otherwise, we need to convert the min and max
- // characters into the min and max characters employed
- // by the DB2 sort sequence. This is complicated by the fact that
- // the character widths are not always equal.
- // 2. Likewise, UCS2 (CCSID 13488) data can be copied across unmodified
- // if it is ucs2_bin or ucs2_general_ci. Otherwise, we need to
- // convert the min and max characters into the min and max characters
- // employed by the DB2 sort sequence.
- // 3. All other data will use standard iconv conversions. If an
- // unconvertible character is encountered, we assume it is the min
- // char and fill the remainder of the DB2 key with 0s. This may not
- // always be accurate, but it is probably sufficient for range
- // estimations.
- const char* keyData = minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0);
- char* db2Data = literalPtr;
- uint16 outLen = db2Field.getByteLengthInRecord();
- uint16 inLen;
- if (litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_VARGRAPHIC)
- {
- inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8);
- keyData += 2;
- outLen -= sizeof(uint16);
- db2Data += sizeof(uint16);
- }
- else
- {
- inLen = field->max_display_length();
- }
-
- size_t convertedBytes = 0;
- if (db2Field.getCCSID() == 1208)
- {
- DBUG_ASSERT(inLen <= outLen);
- if (strcmp(field->charset()->name, "utf8_bin"))
- {
- const char* end = keyData+inLen;
- const char* curKey = keyData;
- char* curDB2 = db2Data;
- uint32 min = field->charset()->min_sort_char;
- while ((curKey < end) && (curDB2 < db2Data+outLen-3))
- {
- my_wc_t temp;
- int len = field->charset()->cset->mb_wc(field->charset(),
- &temp,
- (const uchar*)curKey,
- (const uchar*)end);
- if (temp != min)
- {
- DBUG_ASSERT(len <= 3);
- switch (len)
- {
- case 3: *(curDB2+2) = *(curKey+2);
- case 2: *(curDB2+1) = *(curKey+1);
- case 1: *(curDB2) = *(curKey);
- }
- curDB2 += len;
- }
- else
- {
- *(curDB2++) = 0xEF;
- *(curDB2++) = 0xBF;
- *(curDB2++) = 0xBF;
- }
- curKey += len;
- }
- convertedBytes = curDB2 - db2Data;
- }
- else
- {
- memcpy(db2Data, keyData, inLen);
- convertedBytes = inLen;
- }
- rc = 0;
- }
- else if (db2Field.getCCSID() == 13488)
- {
- DBUG_ASSERT(inLen <= outLen);
- if (strcmp(field->charset()->name, "ucs2_bin") &&
- strcmp(field->charset()->name, "ucs2_general_ci"))
- {
- const char* end = keyData+inLen;
- const uint16* curKey = (uint16*)keyData;
- uint16* curDB2 = (uint16*)db2Data;
- uint16 min = field->charset()->min_sort_char;
- while (curKey < (uint16*)end)
- {
- if (*curKey != min)
- *curDB2 = *curKey;
- else
- *curDB2 = 0xFFFF;
- ++curKey;
- ++curDB2;
- }
- }
- else
- {
- memcpy(db2Data, keyData, inLen);
- }
- convertedBytes = inLen;
- rc = 0;
- }
- else
- {
- rc = convertFieldChars(toDB2,
- field->field_index,
- keyData,
- db2Data,
- inLen,
- outLen,
- &convertedBytes,
- true);
-
- if (rc == DB2I_ERR_ILL_CHAR)
- {
- // If an illegal character is encountered, we fill the remainder
- // of the key with 0x00. This was implemented as a corollary to
- // Bug#45012, though it should probably remain even after that
- // bug is fixed.
- memset(db2Data+convertedBytes, 0x00, outLen-convertedBytes);
- convertedBytes = outLen;
- rc = 0;
- }
- }
-
- if (!rc &&
- (litDefPtr->DataType == QMY_VARGRAPHIC ||
- litDefPtr->DataType == QMY_VARCHAR))
- {
- *(uint16*)(db2Data-sizeof(uint16)) =
- convertedBytes / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1);
- }
-
- }
- else // Non-character fields
- {
- rc = convertMySQLtoDB2(field,
- db2Field,
- literalPtr,
- (uchar*)minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0));
- }
-
- if (rc != 0) break;
- litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr);
- litDefPtr->Length = db2Field.getByteLengthInRecord();
- literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal
- }
- /* If there is a max_key value for this field, and if the max_key value is
- the same as the min_key value, then the low bound literal can be reused
- for the high bound literal. This eliminates the overhead of copying and
- converting the same value twice. */
- if (max_key && ((partsInUse + 1) <= maxKeyCnt) &&
- (memcmp((uchar*)minPtr,(uchar*)maxPtr,
- curKey.key_part[partsInUse].store_length)==0 || endOfLiteralPtr))
- reuseLiteral = true;
- minPtr += curKey.key_part[partsInUse].store_length;
- }
- /*
- Build the high bound for the key range.
- */
- if (max_key == NULL || ((partsInUse + 1) > maxKeyCnt))
- boundsPtr->HiBound.Infinity[0] = QMY_POS_INFINITY;
- else
- {
- if ((curKey.key_part[partsInUse].null_bit) && (char*)maxPtr[0])
- {
- if (min_key == NULL)
- boundsPtr->HiBound.Infinity[0] = QMY_POS_INFINITY;
- else
- boundsPtr->HiBound.IsNull[0] = QMY_YES; // select...where x is null
- }
- else // max_key field is not null
- {
- if (boundsPtr->LoBound.IsNull[0] == QMY_YES) // select where x < 10 or x is null
- {
- rc = HA_POS_ERROR;
- break;
- }
- if (!reuseLiteral)
- {
- if (literalCnt)
- litDefPtr = litDefPtr + 1;
- literalCnt = literalCnt + 1;
- litDefPtr->FieldNbr = field->field_index + 1;
- DB2Field& db2Field = db2Table->db2Field(field->field_index);
- litDefPtr->DataType = db2Field.getType();
- /*
- Convert the literal to DB2 format
- */
- if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data
- (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data
- (litDefPtr->DataType == QMY_CHAR ||
- litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_GRAPHIC ||
- litDefPtr->DataType == QMY_VARGRAPHIC))
- {
- // We need to handle char fields in a special way in order to account
- // for partial keys. Refer to the note above for a description of the
- // basic design.
- char* keyData = maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0);
- char* db2Data = literalPtr;
- uint16 outLen = db2Field.getByteLengthInRecord();
- uint16 inLen;
- if (litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_VARGRAPHIC)
- {
- inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8);
- keyData += 2;
- outLen -= sizeof(uint16);
- db2Data += sizeof(uint16);
- }
- else
- {
- inLen = field->max_display_length();
- }
-
- size_t convertedBytes;
- if (db2Field.getCCSID() == 1208)
- {
- if (strcmp(field->charset()->name, "utf8_bin"))
- {
- const char* end = keyData+inLen;
- const char* curKey = keyData;
- char* curDB2 = db2Data;
- uint32 max = field->charset()->max_sort_char;
- while (curKey < end && (curDB2 < db2Data+outLen-3))
- {
- my_wc_t temp;
- int len = field->charset()->cset->mb_wc(field->charset(), &temp, (const uchar*)curKey, (const uchar*)end);
- if (temp != max)
- {
- DBUG_ASSERT(len <= 3);
- switch (len)
- {
- case 3: *(curDB2+2) = *(curKey+2);
- case 2: *(curDB2+1) = *(curKey+1);
- case 1: *(curDB2) = *(curKey);
- }
- curDB2 += len;
- }
- else
- {
- *(curDB2++) = 0xE4;
- *(curDB2++) = 0xB6;
- *(curDB2++) = 0xBF;
- }
- curKey += len;
- }
- convertedBytes = curDB2 - db2Data;
- }
- else
- {
- DBUG_ASSERT(inLen <= outLen);
- memcpy(db2Data, keyData, inLen);
- convertedBytes = inLen;
- }
- rc = 0;
- }
- else if (db2Field.getCCSID() == 13488)
- {
- if (strcmp(field->charset()->name, "ucs2_bin") &&
- strcmp(field->charset()->name, "ucs2_general_ci"))
- {
- char* end = keyData+inLen;
- uint16* curKey = (uint16*)keyData;
- uint16* curDB2 = (uint16*)db2Data;
- uint16 max = field->charset()->max_sort_char;
- while (curKey < (uint16*)end)
- {
- if (*curKey != max)
- *curDB2 = *curKey;
- else
- *curDB2 = 0x4DBF;
- ++curKey;
- ++curDB2;
- }
- }
- else
- {
- memcpy(db2Data, keyData, outLen);
- }
- rc = 0;
- }
- else
- {
- size_t substituteChars = 0;
- rc = convertFieldChars(toDB2,
- field->field_index,
- keyData,
- db2Data,
- inLen,
- outLen,
- &convertedBytes,
- true,
- &substituteChars);
-
- if (rc == DB2I_ERR_ILL_CHAR)
- {
- // If an illegal character is encountered, we fill the remainder
- // of the key with 0xFF. This was implemented to work around
- // Bug#45012, though it should probably remain even after that
- // bug is fixed.
- memset(db2Data+convertedBytes, 0xFF, outLen-convertedBytes);
- rc = 0;
- }
- else if ((substituteChars &&
- (litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_CHAR)) ||
- strcmp(field->charset()->name, "cp1251_bulgarian_ci") == 0)
- {
- // When iconv translates the max_sort_char with a substitute
- // character, we have no way to know whether this affects
- // the sort order of the key. Therefore, to be safe, when
- // we know that substitute characters have been used in a
- // single-byte string, we traverse the translated key
- // in reverse, replacing substitue characters with 0xFF, which
- // always sorts with the greatest weight in DB2 sort sequences.
- // cp1251_bulgarian_ci is also handled this way because the
- // max_sort_char is a control character which does not sort
- // equivalently in DB2.
- DBUG_ASSERT(inLen == outLen);
- char* tmpKey = keyData + inLen - 1;
- char* tmpDB2 = db2Data + outLen - 1;
- while (*tmpKey == field->charset()->max_sort_char &&
- *tmpDB2 != 0xFF)
- {
- *tmpDB2 = 0xFF;
- --tmpKey;
- --tmpDB2;
- }
- }
- }
-
- if (!rc &&
- (litDefPtr->DataType == QMY_VARGRAPHIC ||
- litDefPtr->DataType == QMY_VARCHAR))
- {
- *(uint16*)(db2Data-sizeof(uint16)) =
- outLen / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1);
- }
- }
- else
- {
- rc = convertMySQLtoDB2(field,
- db2Field,
- literalPtr,
- (uchar*)maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0));
- }
- if (rc != 0) break;
- litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr);
- litDefPtr->Length = db2Field.getByteLengthInRecord();
- literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal
- }
- boundsPtr->HiBound.Position = literalCnt;
- if (max_key->flag == HA_READ_BEFORE_KEY && !overrideInclusion)
- boundsPtr->HiBound.Embodiment[0] = QMY_EXCLUSION;
- }
- maxPtr += curKey.key_part[partsInUse].store_length;
- }
- /*
- Bump to the next field in the key composite.
- */
-
- if ((partsInUse+1) < keyCnt)
- boundsPtr = boundsPtr + 1;
- }
-
- /*
- Call DB2 to estimate the number of rows in the key range.
- */
- if (rc == 0)
- {
- rc = db2i_ileBridge::getBridgeForThread()->recordsInRange((indexHandles[inx] ? indexHandles[inx] : db2Table->indexFile(inx)->getMasterDefnHandle()),
- spcPtr,
- keyCnt,
- literalCnt,
- boundsOff,
- litDefOff,
- literalsOff,
- cutoff,
- (uint32_t)(literalPtr - (char*)spcPtr),
- endByte,
- &recCnt,
- &rtnCode);
- }
- /*
- Set the row count and return.
- Beware that if this method returns a zero row count, MySQL assumes the
- result set for the query is zero; never return a zero row count.
- */
- if ((rc == 0) && (rtnCode == QMY_SUCCESS || rtnCode == QMY_EARLY_EXIT))
- {
- rows = recCnt ? (ha_rows)recCnt : 1;
- }
-
- rows = (rows > 0 ? rows : HA_POS_ERROR);
-
- setIndexReadEstimate(inx, rows);
-
- DBUG_PRINT("ha_ibmdb2i::recordsInRange",("Estimate %d rows for key %d", uint32(rows), inx));
-
- DBUG_RETURN(rows);
-}
diff --git a/storage/ibmdb2i/db2i_safeString.h b/storage/ibmdb2i/db2i_safeString.h
deleted file mode 100644
index e353316c8fc..00000000000
--- a/storage/ibmdb2i/db2i_safeString.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_SAFESTRING_H
-#define DB2I_SAFESTRING_H
-
-
-#include <my_global.h>
-#include <string.h>
-
-/**
- @class SafeString
-
- This class was designed to provide safe, but lightweight, concatenation
- operations C strings inside pre-allocated buffers.
-*/
-class SafeString
-{
-public:
- SafeString(char* buffer, size_t size) :
- allocSize(size), curPos(0), buf(buffer)
- {
- DBUG_ASSERT(size > 0);
- buf[allocSize - 1] = 0xFF; // Set an overflow indicator
- }
-
- char* ptr() { return buf; }
- operator char*() { return buf; }
-
- SafeString& strcat(const char* str)
- {
- return this->strncat(str, strlen(str));
- }
-
- SafeString& strcat(char one)
- {
- if (curPos < allocSize - 2)
- {
- buf[curPos++] = one;
- }
- buf[curPos] = 0;
-
- return *this;
- }
-
- SafeString& strncat(const char* str, size_t len)
- {
- uint64 amountToCopy = min((allocSize-1) - curPos, len);
- memcpy(buf + curPos, str, amountToCopy);
- curPos += amountToCopy;
- buf[curPos] = 0;
- return *this;
- }
-
- bool overflowed() const { return (buf[allocSize - 1] == 0);}
-
-private:
- char* buf;
- uint64 curPos;
- size_t allocSize;
-};
-
-
-#endif
diff --git a/storage/ibmdb2i/db2i_sqlStatementStream.cc b/storage/ibmdb2i/db2i_sqlStatementStream.cc
deleted file mode 100644
index 92a8b03fd00..00000000000
--- a/storage/ibmdb2i/db2i_sqlStatementStream.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 "db2i_sqlStatementStream.h"
-#include "as400_types.h"
-
-/**
- Add a statement to the statement stream, allocating additional memory as needed.
-
- @parm stmt The statement text
- @parm length The length of the statement text
- @parm fileSortSequence The DB2 sort sequence identifier, in EBCDIC
- @parm fileSortSequenceLibrary The DB2 sort sequence library, in EBCDIC
-
- @return Reference to this object
-*/
-SqlStatementStream& SqlStatementStream::addStatementInternal(const char* stmt,
- uint32 length,
- const char* fileSortSequence,
- const char* fileSortSequenceLibrary)
-{
- uint32 storageNeeded = length + sizeof(StmtHdr_t);
- storageNeeded = (storageNeeded + 3) & ~3; // We have to be 4-byte aligned.
- if (storageNeeded > storageRemaining())
- {
- // We overallocate new storage to reduce number of times reallocation is
- // needed.
- int newSize = curSize + 2 * storageNeeded;
- DBUG_PRINT("SqlStatementStream::addStatementInternal",
- ("PERF: Had to realloc! Old size=%d. New size=%d", curSize, newSize));
- char* old_space = block;
- char* new_space = (char*)getNewSpace(newSize);
- memcpy(new_space, old_space, curSize);
- ptr = new_space + (ptr - old_space);
- curSize = newSize;
- }
-
- DBUG_ASSERT((address64_t)ptr % 4 == 0);
-
- memcpy(((StmtHdr_t*)ptr)->SrtSeqNam,
- fileSortSequence,
- sizeof(((StmtHdr_t*)ptr)->SrtSeqNam));
- memcpy(((StmtHdr_t*)ptr)->SrtSeqSch,
- fileSortSequenceLibrary,
- sizeof(((StmtHdr_t*)ptr)->SrtSeqSch));
- ((StmtHdr_t*)ptr)->Length = length;
- memcpy(ptr + sizeof(StmtHdr_t), stmt, length);
-
- ptr += storageNeeded;
- ++statements;
-
- return *this;
-}
diff --git a/storage/ibmdb2i/db2i_sqlStatementStream.h b/storage/ibmdb2i/db2i_sqlStatementStream.h
deleted file mode 100644
index 11db41a6c5d..00000000000
--- a/storage/ibmdb2i/db2i_sqlStatementStream.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_SQLSTATEMENTSTREAM_H
-#define DB2I_SQLSTATEMENTSTREAM_H
-
-#include "db2i_charsetSupport.h"
-#include "qmyse.h"
-
-/**
- @class SqlStatementStream
-
- This class handles building the stream of SQL statements expected by the
- QMY_EXECUTE_IMMEDIATE and QMY_PREPARE_OPEN_CURSOR APIs.
- Memory allocation is handled internally.
-*/
-class SqlStatementStream
-{
- public:
- /**
- ctor to be used when multiple strings may be appended.
- */
- SqlStatementStream(uint32 firstStringSize) : statements(0)
- {
- curSize = firstStringSize + sizeof(StmtHdr_t);
- curSize = (curSize + 3) & ~3;
- ptr = (char*) getNewSpace(curSize);
- if (ptr == NULL)
- curSize = 0;
- }
-
- /**
- ctor to be used when only a single statement will be executed.
- */
- SqlStatementStream(const String& statement) : statements(0), block(NULL), curSize(0), ptr(0)
- {
- addStatement(statement);
- }
-
- /**
- ctor to be used when only a single statement will be executed.
- */
- SqlStatementStream(const char* statement) : statements(0), block(NULL), curSize(0), ptr(0)
- {
- addStatement(statement);
- }
-
- /**
- Append an SQL statement, specifiying the DB2 sort sequence under which
- the statement should be executed. This is important for CREATE TABLE
- and CREATE INDEX statements.
- */
- SqlStatementStream& addStatement(const String& append, const char* fileSortSequence, const char* fileSortSequenceLibrary)
- {
- char sortSeqEbcdic[10];
- char sortSeqLibEbcdic[10];
-
- DBUG_ASSERT(strlen(fileSortSequence) <= 10 &&
- strlen(fileSortSequenceLibrary) <= 10);
- memset(sortSeqEbcdic, 0x40, 10);
- memset(sortSeqLibEbcdic, 0x40, 10);
- convToEbcdic(fileSortSequence, sortSeqEbcdic, strlen(fileSortSequence));
- convToEbcdic(fileSortSequenceLibrary, sortSeqLibEbcdic, strlen(fileSortSequenceLibrary));
-
- return addStatementInternal(append.ptr(), append.length(), sortSeqEbcdic, sortSeqLibEbcdic);
- }
-
- /**
- Append an SQL statement using default (*HEX) sort sequence.
- */
- SqlStatementStream& addStatement(const String& append)
- {
- const char splatHEX[] = {0x5C, 0xC8, 0xC5, 0xE7, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // *HEX
- const char blanks[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; //
-
- return addStatementInternal(append.ptr(), append.length(), splatHEX, blanks);
- }
-
- /**
- Append an SQL statement using default (*HEX) sort sequence.
- */
- SqlStatementStream& addStatement(const char* stmt)
- {
- const char splatHEX[] = {0x5C, 0xC8, 0xC5, 0xE7, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // *HEX
- const char blanks[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; //
-
- return addStatementInternal(stmt, strlen(stmt), splatHEX, blanks);
- }
-
- char* getPtrToData() const { return block; }
- uint32 getStatementCount() const { return statements; }
- private:
- SqlStatementStream& addStatementInternal(const char* stmt,
- uint32 length,
- const char* fileSortSequence,
- const char* fileSortSequenceLibrary);
-
- uint32 storageRemaining() const
- {
- return (block == NULL ? 0 : curSize - (ptr - block));
- }
-
- char* getNewSpace(size_t size)
- {
- allocBase = (char*)sql_alloc(size + 15);
- block = (char*)roundToQuadWordBdy(allocBase);
- return block;
- }
-
- uint32 curSize; // The size of the usable memory.
- char* allocBase; // The allocated memory (with padding for aligment)
- char* block; // The usable memory chunck (aligned for ILE)
- char* ptr; // The current position within block.
- uint32 statements; // The number of statements that have been appended.
-};
-
-#endif
-
diff --git a/storage/ibmdb2i/db2i_validatedPointer.h b/storage/ibmdb2i/db2i_validatedPointer.h
deleted file mode 100644
index c4e31d1f11b..00000000000
--- a/storage/ibmdb2i/db2i_validatedPointer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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 DB2I_VALIDATEDPOINTER_H
-#define DB2I_VALIDATEDPOINTER_H
-
-#include "db2i_ileBridge.h"
-
-/**
- @class ValidatedPointer
- @brief Encapsulates a pointer registered for usage by the QMYSE APIs
-
- @details As a performance optimization, to prevent pointer validation each
- time a particular pointer is thunked across to ILE, QMYSE allows us to
- "register" a pointer such that it is validated once and then subsequently
- referenced on QMYSE APIs by means of a handle value. This class should be
- used to manage memory allocation/registration/unregistration of these
- pointers. Using the alloc function guarantees that the resulting storage is
- 16-byte aligned, a requirement for many pointers passed to QMYSE.
-*/
-template <class T>
-class ValidatedPointer
-{
-public:
- ValidatedPointer<T>() : address(NULL), handle(NULL) {;}
-
- ValidatedPointer<T>(size_t size)
- {
- alloc(size);
- }
-
- ValidatedPointer<T>(T* ptr)
- {
- assign(ptr);
- }
-
- operator T*()
- {
- return address;
- };
-
- operator T*() const
- {
- return address;
- };
-
- operator void*()
- {
- return address;
- };
-
- operator ILEMemHandle()
- {
- return handle;
- }
-
- void alloc(size_t size)
- {
- address = (T*)malloc_aligned(size);
- if (address)
- db2i_ileBridge::registerPtr(address, &handle);
- mallocedHere = 1;
- }
-
- void assign(T* ptr)
- {
- address = ptr;
- db2i_ileBridge::registerPtr((void*)ptr, &handle);
- mallocedHere = 0;
- }
-
- void realloc(size_t size)
- {
- dealloc();
- alloc(size);
- }
-
- void reassign(T* ptr)
- {
- dealloc();
- assign(ptr);
- }
-
- void dealloc()
- {
- if (address)
- {
- db2i_ileBridge::unregisterPtr(handle);
-
- if (mallocedHere)
- free_aligned((void*)address);
- }
- address = NULL;
- handle = 0;
- }
-
- ~ValidatedPointer()
- {
- dealloc();
- }
-
-private:
- // Disable copy ctor and assignment operator, as these would break
- // the registration guarantees provided by the class.
- ValidatedPointer& operator= (const ValidatedPointer newVal);
- ValidatedPointer(ValidatedPointer& newCopy);
-
- ILEMemHandle handle;
- T* address;
- char mallocedHere;
-};
-
-
-/**
- @class ValidatedObject
- @brief This class allows users to instantiate and register a particular
- object in a single step.
-*/
-template<class T>
-class ValidatedObject : public ValidatedPointer<T>
-{
- public:
- ValidatedObject<T>() : ValidatedPointer<T>(&value) {;}
-
- T& operator= (const T newVal) { value = newVal; return value; }
-
- private:
- T value;
-};
-#endif
diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc
deleted file mode 100644
index 39096be7848..00000000000
--- a/storage/ibmdb2i/ha_ibmdb2i.cc
+++ /dev/null
@@ -1,3359 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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.
-*/
-
-
-/**
- @file ha_ibmdb2i.cc
-
- @brief
- The ha_ibmdb2i storage engine provides an interface from MySQL to IBM DB2 for i.
-
-*/
-
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "ha_ibmdb2i.h"
-#include "mysql_priv.h"
-#include <mysql/plugin.h>
-#include "db2i_ileBridge.h"
-#include "db2i_charsetSupport.h"
-#include <sys/utsname.h>
-#include "db2i_safeString.h"
-
-static const char __NOT_NULL_VALUE_EBCDIC = 0xF0; // '0'
-static const char __NULL_VALUE_EBCDIC = 0xF1; // '1'
-static const char __DEFAULT_VALUE_EBCDIC = 0xC4; // 'D'
-static const char BlankASPName[19] = " ";
-static const int DEFAULT_MAX_ROWS_TO_BUFFER = 4096;
-
-static const char SAVEPOINT_PREFIX[] = {0xD4, 0xE8, 0xE2, 0xD7}; // MYSP (in EBCDIC)
-
-OSVersion osVersion;
-
-
-// ================================================================
-// ================================================================
-// System variables
-static char* ibmdb2i_rdb_name;
-static MYSQL_SYSVAR_STR(rdb_name, ibmdb2i_rdb_name,
- PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY,
- "The name of the RDB to use",
- NULL,
- NULL,
- BlankASPName);
-
-static MYSQL_THDVAR_BOOL(transaction_unsafe,
- 0,
- "Disable support for commitment control",
- NULL,
- NULL,
- FALSE);
-
-static MYSQL_THDVAR_UINT(lob_alloc_size,
- 0,
- "Baseline allocation for lob read buffer",
- NULL,
- NULL,
- 2*1024*1024,
- 64*1024,
- 128*1024*1024,
- 1);
-
-static MYSQL_THDVAR_UINT(max_read_buffer_size,
- 0,
- "Maximum size of buffers used for read-ahead.",
- NULL,
- NULL,
- 1*1024*1024,
- 32*1024,
- 16*1024*1024,
- 1);
-
-static MYSQL_THDVAR_UINT(max_write_buffer_size,
- 0,
- "Maximum size of buffers used for bulk writes.",
- NULL,
- NULL,
- 8*1024*1024,
- 32*1024,
- 64*1024*1024,
- 1);
-
-static MYSQL_THDVAR_BOOL(compat_opt_time_as_duration,
- 0,
- "Control how new TIME columns should be defined in DB2. 0=time-of-day (default), 1=duration.",
- NULL,
- NULL,
- FALSE);
-
-static MYSQL_THDVAR_UINT(compat_opt_year_as_int,
- 0,
- "Control how new YEAR columns should be defined in DB2. 0=CHAR(4) (default), 1=SMALLINT.",
- NULL,
- NULL,
- 0,
- 0,
- 1,
- 1);
-
-static MYSQL_THDVAR_UINT(compat_opt_blob_cols,
- 0,
- "Control how new TEXT and BLOB columns should be defined in DB2. 0=CLOB/BLOB (default), 1=VARCHAR/VARBINARY",
- NULL,
- NULL,
- 0,
- 0,
- 1,
- 1);
-
-static MYSQL_THDVAR_UINT(compat_opt_allow_zero_date_vals,
- 0,
- "Allow substitute values to be used when storing a column with a 0000-00-00 date component. 0=No substitution (default), 1=Substitute '0001-01-01'",
- NULL,
- NULL,
- 0,
- 0,
- 1,
- 1);
-
-static MYSQL_THDVAR_BOOL(propagate_default_col_vals,
- 0,
- "Should DEFAULT column values be propagated to the DB2 table definition.",
- NULL,
- NULL,
- TRUE);
-
-static my_bool ibmdb2i_assume_exclusive_use;
-static MYSQL_SYSVAR_BOOL(assume_exclusive_use, ibmdb2i_assume_exclusive_use,
- 0,
- "Can MySQL assume that this process is the only one modifying the DB2 tables. ",
- NULL,
- NULL,
- FALSE);
-
-static MYSQL_THDVAR_BOOL(async_enabled,
- 0,
- "Should reads be done asynchronously when possible",
- NULL,
- NULL,
- TRUE);
-
-static MYSQL_THDVAR_UINT(create_index_option,
- 0,
- "Control whether additional indexes are created. 0=No (default), 1=Create additional *HEX-based index",
- NULL,
- NULL,
- 0,
- 0,
- 1,
- 1);
-
-/* static MYSQL_THDVAR_UINT(discovery_mode,
- 0,
- "Unsupported",
- NULL,
- NULL,
- 0,
- 0,
- 1,
- 1); */
-
-static uint32 ibmdb2i_system_trace;
-static MYSQL_SYSVAR_UINT(system_trace_level, ibmdb2i_system_trace,
- 0,
- "Set system tracing level",
- NULL,
- NULL,
- 0,
- 0,
- 63,
- 1);
-
-
-inline uint8 ha_ibmdb2i::getCommitLevel(THD* thd)
-{
- if (!THDVAR(thd, transaction_unsafe))
- {
- switch (thd_tx_isolation(thd))
- {
- case ISO_READ_UNCOMMITTED:
- return (accessIntent == QMY_READ_ONLY ? QMY_READ_UNCOMMITTED : QMY_REPEATABLE_READ);
- case ISO_READ_COMMITTED:
- return (accessIntent == QMY_READ_ONLY ? QMY_READ_COMMITTED : QMY_REPEATABLE_READ);
- case ISO_REPEATABLE_READ:
- return QMY_REPEATABLE_READ;
- case ISO_SERIALIZABLE:
- return QMY_SERIALIZABLE;
- }
- }
-
- return QMY_NONE;
-}
-
-inline uint8 ha_ibmdb2i::getCommitLevel()
-{
- return getCommitLevel(ha_thd());
-}
-
-//=====================================================================
-
-static handler *ibmdb2i_create_handler(handlerton *hton,
- TABLE_SHARE *table,
- MEM_ROOT *mem_root);
-static void ibmdb2i_drop_database(handlerton *hton, char* path);
-static int ibmdb2i_savepoint_set(handlerton *hton, THD* thd, void *sv);
-static int ibmdb2i_savepoint_rollback(handlerton *hton, THD* thd, void *sv);
-static int ibmdb2i_savepoint_release(handlerton *hton, THD* thd, void *sv);
-static uint ibmdb2i_alter_table_flags(uint flags);
-
-handlerton *ibmdb2i_hton;
-static bool was_ILE_inited;
-
-/* Tracks the number of open tables */
-static HASH ibmdb2i_open_tables;
-
-/* Mutex used to synchronize initialization of the hash */
-static pthread_mutex_t ibmdb2i_mutex;
-
-
-/**
- Create hash key for tracking open tables.
-*/
-
-static uchar* ibmdb2i_get_key(IBMDB2I_SHARE *share,size_t *length,
- bool not_used __attribute__((unused)))
-{
- *length=share->table_name_length;
- return (uchar*) share->table_name;
-}
-
-
-int ibmdb2i_close_connection(handlerton* hton, THD *thd)
-{
- DBUG_PRINT("ha_ibmdb2i::close_connection", ("Closing %d", thd->thread_id));
- db2i_ileBridge::getBridgeForThread(thd)->closeConnection(thd->thread_id);
- db2i_ileBridge::destroyBridgeForThread(thd);
-
- return 0;
-}
-
-
-static int ibmdb2i_init_func(void *p)
-{
- DBUG_ENTER("ibmdb2i_init_func");
-
- utsname tempName;
- uname(&tempName);
- osVersion.v = atoi(tempName.version);
- osVersion.r = atoi(tempName.release);
-
- was_ILE_inited = false;
- ibmdb2i_hton= (handlerton *)p;
- VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST));
- (void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0,
- (hash_get_key) ibmdb2i_get_key,0,0);
-
- ibmdb2i_hton->state= SHOW_OPTION_YES;
- ibmdb2i_hton->create= ibmdb2i_create_handler;
- ibmdb2i_hton->drop_database= ibmdb2i_drop_database;
- ibmdb2i_hton->commit= ha_ibmdb2i::doCommit;
- ibmdb2i_hton->rollback= ha_ibmdb2i::doRollback;
- ibmdb2i_hton->savepoint_offset= 0;
- ibmdb2i_hton->savepoint_set= ibmdb2i_savepoint_set;
- ibmdb2i_hton->savepoint_rollback= ibmdb2i_savepoint_rollback;
- ibmdb2i_hton->savepoint_release= ibmdb2i_savepoint_release;
- ibmdb2i_hton->alter_table_flags=ibmdb2i_alter_table_flags;
- ibmdb2i_hton->close_connection=ibmdb2i_close_connection;
-
- int rc;
-
- rc = initCharsetSupport();
-
- if (!rc)
- rc = db2i_ileBridge::setup();
-
- if (!rc)
- {
- int nameLen = strlen(ibmdb2i_rdb_name);
- for (int i = 0; i < nameLen; ++i)
- {
- ibmdb2i_rdb_name[i] = my_toupper(system_charset_info, (uchar)ibmdb2i_rdb_name[i]);
- }
-
- rc = db2i_ileBridge::initILE(ibmdb2i_rdb_name, (uint16*)(((char*)&ibmdb2i_system_trace)+2));
- if (rc == 0)
- {
- was_ILE_inited = true;
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-
-static int ibmdb2i_done_func(void *p)
-{
- int error= 0;
- DBUG_ENTER("ibmdb2i_done_func");
-
- if (ibmdb2i_open_tables.records)
- error= 1;
-
- if (was_ILE_inited)
- db2i_ileBridge::exitILE();
-
- db2i_ileBridge::takedown();
-
- doneCharsetSupport();
-
- hash_free(&ibmdb2i_open_tables);
- pthread_mutex_destroy(&ibmdb2i_mutex);
-
- DBUG_RETURN(0);
-}
-
-
-IBMDB2I_SHARE *ha_ibmdb2i::get_share(const char *table_name, TABLE *table)
-{
- IBMDB2I_SHARE *share;
- uint length;
- char *tmp_name;
-
- pthread_mutex_lock(&ibmdb2i_mutex);
- length=(uint) strlen(table_name);
-
- if (!(share=(IBMDB2I_SHARE*) hash_search(&ibmdb2i_open_tables,
- (uchar*)table_name,
- length)))
- {
- if (!(share=(IBMDB2I_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &share, sizeof(*share),
- &tmp_name, length+1,
- NullS)))
- {
- pthread_mutex_unlock(&ibmdb2i_mutex);
- return NULL;
- }
-
- share->use_count=0;
- share->table_name_length=length;
- share->table_name=tmp_name;
- strmov(share->table_name,table_name);
- if (my_hash_insert(&ibmdb2i_open_tables, (uchar*) share))
- goto error;
- thr_lock_init(&share->lock);
- pthread_mutexattr_t mutexattr = MY_MUTEX_INIT_FAST;
- pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&share->mutex, &mutexattr);
-
- share->db2Table = new db2i_table(table->s, table_name);
- int32 rc = share->db2Table->initDB2Objects(table_name);
-
- if (rc)
- {
- delete share->db2Table;
- hash_delete(&ibmdb2i_open_tables, (uchar*) share);
- thr_lock_delete(&share->lock);
- my_errno = rc;
- goto error;
- }
-
- memset(&share->cachedStats, 0, sizeof(share->cachedStats));
- }
- share->use_count++;
- pthread_mutex_unlock(&ibmdb2i_mutex);
-
- db2Table = share->db2Table;
-
- return share;
-
-error:
- pthread_mutex_destroy(&share->mutex);
- my_free((uchar*) share, MYF(0));
- pthread_mutex_unlock(&ibmdb2i_mutex);
-
- return NULL;
-}
-
-
-
-int ha_ibmdb2i::free_share(IBMDB2I_SHARE *share)
-{
- pthread_mutex_lock(&ibmdb2i_mutex);
- if (!--share->use_count)
- {
- delete share->db2Table;
- db2Table = NULL;
-
- hash_delete(&ibmdb2i_open_tables, (uchar*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free(share, MYF(0));
- pthread_mutex_unlock(&ibmdb2i_mutex);
- return 1;
- }
- pthread_mutex_unlock(&ibmdb2i_mutex);
-
- return 0;
-}
-
-static handler* ibmdb2i_create_handler(handlerton *hton,
- TABLE_SHARE *table,
- MEM_ROOT *mem_root)
-{
- return new (mem_root) ha_ibmdb2i(hton, table);
-}
-
-static void ibmdb2i_drop_database(handlerton *hton, char* path)
-{
- DBUG_ENTER("ha_ibmdb2i::ibmdb2i_drop_database");
- int rc = 0;
- char queryBuffer[200];
- String query(queryBuffer, sizeof(queryBuffer), system_charset_info);
- query.length(0);
- query.append(STRING_WITH_LEN(" DROP SCHEMA \""));
- query.append(path+2, strchr(path+2, '/')-(path+2));
- query.append('"');
-
- SqlStatementStream sqlStream(query);
-
- rc = db2i_ileBridge::getBridgeForThread()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- QMY_NONE,
- FALSE,
- TRUE);
- DBUG_VOID_RETURN;
-}
-
-inline static void genSavepointName(const void* sv, char* out)
-{
- *(uint32*)out = *(uint32*)SAVEPOINT_PREFIX;
- DBUG_ASSERT(sizeof(SAVEPOINT_PREFIX) == 4);
- out += sizeof(SAVEPOINT_PREFIX);
-
- longlong2str((longlong)sv, out, 10);
- while (*out)
- {
- out += 0xF0;
- ++out;
- }
-}
-
-
-/*********************************************************************
-Sets a transaction savepoint. */
-static int ibmdb2i_savepoint_set(handlerton* hton, THD* thd, void* sv)
-{
- DBUG_ENTER("ibmdb2i_savepoint_set");
- int rc = 0;
- if (!THDVAR(thd ,transaction_unsafe))
- {
- char name[64];
- genSavepointName(sv, name);
- DBUG_PRINT("ibmdb2i_savepoint_set",("Setting %s", name));
- rc = ha_ibmdb2i::doSavepointSet(thd, name);
- }
- DBUG_RETURN(rc);
-}
-
-
-/*********************************************************************
-Rollback a savepoint. */
-static int ibmdb2i_savepoint_rollback(handlerton* hton, THD* thd, void* sv)
-{
- DBUG_ENTER("ibmdb2i_savepoint_rollback");
- int rc = 0;
- if (!THDVAR(thd,transaction_unsafe))
- {
- char name[64];
- genSavepointName(sv, name);
- DBUG_PRINT("ibmdb2i_savepoint_rollback",("Rolling back %s", name));
- rc = ha_ibmdb2i::doSavepointRollback(thd, name);
- }
- DBUG_RETURN(rc);
-}
-
-
-/*********************************************************************
-Release a savepoint. */
-static int ibmdb2i_savepoint_release(handlerton* hton, THD* thd, void* sv)
-{
- DBUG_ENTER("ibmdb2i_savepoint_release");
- int rc = 0;
- if (!THDVAR(thd,transaction_unsafe))
- {
- char name[64];
- genSavepointName(sv, name);
- DBUG_PRINT("ibmdb2i_savepoint_release",("Releasing %s", name));
- rc = ha_ibmdb2i::doSavepointRelease(thd, name);
- }
- DBUG_RETURN(rc);
-}
-
-/* Thse flags allow for the online add and drop of an index via the CREATE INDEX,
- DROP INDEX, and ALTER TABLE statements. These flags indicate that MySQL is not
- required to lock the table before calling the storage engine to add or drop the
- index(s). */
-static uint ibmdb2i_alter_table_flags(uint flags)
-{
- return (HA_ONLINE_ADD_INDEX | HA_ONLINE_DROP_INDEX |
- HA_ONLINE_ADD_UNIQUE_INDEX | HA_ONLINE_DROP_UNIQUE_INDEX |
- HA_ONLINE_ADD_PK_INDEX | HA_ONLINE_DROP_PK_INDEX);
-}
-
-ha_ibmdb2i::ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg)
- :share(NULL), handler(hton, table_arg),
- activeHandle(0), dataHandle(0),
- activeReadBuf(NULL), activeWriteBuf(NULL),
- blobReadBuffers(NULL), accessIntent(QMY_UPDATABLE), currentRRN(0),
- releaseRowNeeded(FALSE),
- indexReadSizeEstimates(NULL),
- outstanding_start_bulk_insert(false),
- last_rnd_init_rc(0),
- last_index_init_rc(0),
- last_start_bulk_insert_rc(0),
- autoIncLockAcquired(false),
- got_auto_inc_values(false),
- next_identity_value(0),
- indexHandles(0),
- returnDupKeysImmediately(false),
- onDupUpdate(false),
- blobWriteBuffers(NULL),
- forceSingleRowRead(false)
- {
- activeReferences = 0;
- ref_length = sizeof(currentRRN);
- if (table_share && table_share->keys > 0)
- {
- indexHandles = (FILE_HANDLE*)my_malloc(table_share->keys * sizeof(FILE_HANDLE), MYF(MY_WME | MY_ZEROFILL));
- }
- clear_alloc_root(&conversionBufferMemroot);
- }
-
-
-ha_ibmdb2i::~ha_ibmdb2i()
-{
- DBUG_ASSERT(activeReferences == 0 || outstanding_start_bulk_insert);
-
- if (indexHandles)
- my_free(indexHandles, MYF(0));
- if (indexReadSizeEstimates)
- my_free(indexReadSizeEstimates, MYF(0));
-
- cleanupBuffers();
-}
-
-
-static const char *ha_ibmdb2i_exts[] = {
- FID_EXT,
- NullS
-};
-
-const char **ha_ibmdb2i::bas_ext() const
-{
- return ha_ibmdb2i_exts;
-}
-
-
-int ha_ibmdb2i::open(const char *name, int mode, uint test_if_locked)
-{
- DBUG_ENTER("ha_ibmdb2i::open");
-
- initBridge();
-
- dataHandle = bridge()->findAndRemovePreservedHandle(name, &share);
-
- if (share)
- db2Table = share->db2Table;
-
- if (!share && (!(share = get_share(name, table))))
- DBUG_RETURN(my_errno);
- thr_lock_data_init(&share->lock,&lock,NULL);
-
- info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
-
-
- DBUG_RETURN(0);
-}
-
-
-
-
-int ha_ibmdb2i::close(void)
-{
- DBUG_ENTER("ha_ibmdb2i::close");
- int32 rc = 0;
- bool preserveShare = false;
-
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread();
-
- if (dataHandle)
- {
- if (bridge->expectErrors(QMY_ERR_PEND_LOCKS)->deallocateFile(dataHandle, FALSE) == QMY_ERR_PEND_LOCKS)
- {
- bridge->preserveHandle(share->table_name, dataHandle, share);
- preserveShare = true;
- }
- dataHandle = 0;
- }
-
- for (int idx = 0; idx < table_share->keys; ++idx)
- {
- if (indexHandles[idx] != 0)
- {
- bridge->deallocateFile(indexHandles[idx], FALSE);
- }
- }
-
- cleanupBuffers();
-
- if (!preserveShare)
- {
- if (free_share(share))
- share = NULL;
- }
-
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::write_row(uchar * buf)
-{
-
- DBUG_ENTER("ha_ibmdb2i::write_row");
-
- if (last_start_bulk_insert_rc)
- DBUG_RETURN( last_start_bulk_insert_rc );
-
- ha_statistic_increment(&SSV::ha_write_count);
- int rc = 0;
-
- bool fileHandleNeedsRelease = false;
-
- if (!activeHandle)
- {
- rc = useDataFile();
- if (rc) DBUG_RETURN(rc);
- fileHandleNeedsRelease = true;
- }
-
- if (!outstanding_start_bulk_insert)
- rc = prepWriteBuffer(1, getFileForActiveHandle());
-
- if (!rc)
- {
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
- char* writeBuffer = activeWriteBuf->addRow();
- rc = prepareRowForWrite(writeBuffer,
- writeBuffer+activeWriteBuf->getRowNullOffset(),
- true);
- if (rc == 0)
- {
- // If we are doing block inserts, if the MI is supposed to generate an auto_increment
- // (i.e. identity column) value for this record, and if this is not the first record in
- // the block, then store the value (that the MI will generate for the identity column)
- // into the MySQL write buffer. We can predetermine the value because the file is locked.
-
- if ((autoIncLockAcquired) && (default_identity_value) && (got_auto_inc_values))
- {
- if (unlikely((next_identity_value - 1) ==
- maxValueForField(table->next_number_field)))
- {
- rc = QMY_ERR_MAXVALUE;
- }
- else
- {
- rc = table->next_number_field->store((longlong) next_identity_value, TRUE);
- next_identity_value = next_identity_value + incrementByValue;
- }
- }
- // If the buffer is full, or if we locked the file and this is the first or last row
- // of a blocked insert, then flush the buffer.
- if (!rc && (activeWriteBuf->endOfBuffer()) ||
- ((autoIncLockAcquired) &&
- ((!got_auto_inc_values))) ||
- (returnDupKeysImmediately))
- rc = flushWrite(activeHandle, buf);
- }
- else
- activeWriteBuf->deleteRow();
- }
-
- if (fileHandleNeedsRelease)
- releaseActiveHandle();
-
- DBUG_RETURN(rc);
-}
-
-/**
- @brief
- Helper function used by write_row and update_row to prepare the MySQL
- row for insertion into DB2.
-*/
-int ha_ibmdb2i::prepareRowForWrite(char* data, char* nulls, bool honorIdentCols)
-{
- int rc = 0;
-
- // set null map all to non nulls
- memset(nulls,__NOT_NULL_VALUE_EBCDIC, table->s->fields);
- default_identity_value = FALSE;
-
- ulong sql_mode = ha_thd()->variables.sql_mode;
-
- my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
- for (Field **field = table->field; *field && !rc; ++field)
- {
- int fieldIndex = (*field)->field_index;
- if ((*field)->Field::is_null())
- {
- nulls[fieldIndex] = __NULL_VALUE_EBCDIC;
- }
- if (honorIdentCols && ((*field)->flags & AUTO_INCREMENT_FLAG) &&
- *field == table->next_number_field)
-// && ((!autoIncLockAcquired) || (!got_auto_inc_values)))
- {
- if (sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)
- {
- if (!table->auto_increment_field_not_null)
- {
- nulls[fieldIndex] = __DEFAULT_VALUE_EBCDIC;
- default_identity_value = TRUE;
- }
- }
- else if ((*field)->val_int() == 0)
- {
- nulls[fieldIndex] = __DEFAULT_VALUE_EBCDIC;
- default_identity_value = TRUE;
- }
- }
-
- DB2Field& db2Field = db2Table->db2Field(fieldIndex);
- if (nulls[fieldIndex] == __NOT_NULL_VALUE_EBCDIC ||
- db2Field.isBlob())
- {
- rc = convertMySQLtoDB2(*field, db2Field, data + db2Field.getBufferOffset());
- }
- }
-
- if (!rc && db2Table->hasBlobs())
- rc = db2i_ileBridge::getBridgeForThread()->objectOverride(activeHandle,
- activeWriteBuf->ptr());
-
- dbug_tmp_restore_column_map(table->read_set, old_map);
-
- return rc;
-}
-
-
-
-int ha_ibmdb2i::update_row(const uchar * old_data, uchar * new_data)
-{
- DBUG_ENTER("ha_ibmdb2i::update_row");
- ha_statistic_increment(&SSV::ha_update_count);
- int rc;
-
- bool fileHandleNeedsRelease = false;
-
- if (!activeHandle)
- {
- rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle);
- if (rc) DBUG_RETURN(rc);
- fileHandleNeedsRelease = true;
- }
-
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
-
- char* writeBuf = activeWriteBuf->addRow();
- rc = prepareRowForWrite(writeBuf,
- writeBuf+activeWriteBuf->getRowNullOffset(),
- onDupUpdate);
-
- char* lastDupKeyNamePtr = NULL;
- uint32 lastDupKeyNameLen = 0;
-
- if (!rc)
- {
- rc = db2i_ileBridge::getBridgeForThread()->updateRow(activeHandle,
- currentRRN,
- activeWriteBuf->ptr(),
- &lastDupKeyRRN,
- &lastDupKeyNamePtr,
- &lastDupKeyNameLen);
- }
-
- if (lastDupKeyNameLen)
- {
- lastDupKeyID = getKeyFromName(lastDupKeyNamePtr, lastDupKeyNameLen);
- rrnAssocHandle = activeHandle;
- }
-
- if (fileHandleNeedsRelease)
- releaseActiveHandle();
-
- activeWriteBuf->resetAfterWrite();
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::delete_row(const uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::delete_row");
- ha_statistic_increment(&SSV::ha_delete_count);
-
- bool needReleaseFile = false;
- int rc = 0;
-
- if (!activeHandle) // In some circumstances, MySQL comes here after
- { // closing the active handle. We need to re-open.
- rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle);
- needReleaseFile = true;
- }
-
- if (likely(!rc))
- {
- rc = db2i_ileBridge::getBridgeForThread()->deleteRow(activeHandle,
- currentRRN);
- invalidateCachedStats();
- if (needReleaseFile)
- releaseActiveHandle();
- }
-
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::index_init(uint idx, bool sorted)
-{
- DBUG_ENTER("ha_ibmdb2i::index_init");
-
- int& rc = last_index_init_rc;
- rc = 0;
-
- invalidDataFound=false;
- tweakReadSet();
-
- active_index=idx;
-
- rc = useIndexFile(idx);
-
- if (!rc)
- {
-// THD* thd = ha_thd();
-// if (accessIntent == QMY_UPDATABLE &&
-// thd_tx_isolation(thd) == ISO_REPEATABLE_READ &&
-// !THDVAR(thd, transaction_unsafe))
-// {
-// readAccessIntent = QMY_READ_ONLY;
-// }
-// else
-// {
- readAccessIntent = accessIntent;
-// }
-
- if (!rc && accessIntent != QMY_READ_ONLY)
- rc = prepWriteBuffer(1, db2Table->indexFile(idx));
-
- if (rc)
- releaseIndexFile(idx);
- }
-
- rrnAssocHandle= 0;
-
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::index_read(uchar * buf, const uchar * key,
- uint key_len,
- enum ha_rkey_function find_flag)
-{
- DBUG_ENTER("ha_ibmdb2i::index_read");
-
- if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc);
-
- int rc;
-
- ha_rows estimatedRows = getIndexReadEstimate(active_index);
- rc = prepReadBuffer(estimatedRows, db2Table->indexFile(active_index), readAccessIntent);
- if (unlikely(rc)) DBUG_RETURN(rc);
-
- DBUG_ASSERT(activeReadBuf);
-
- keyBuf.allocBuf(activeReadBuf->getRowLength(),
- activeReadBuf->getRowNullOffset(),
- activeReadBuf->getRowLength());
- keyBuf.zeroBuf();
-
- char* db2KeyBufPtr = keyBuf.ptr();
- char* nullKeyMap = db2KeyBufPtr + activeReadBuf->getRowNullOffset();
-
- const uchar* keyBegin = key;
- int partsInUse;
-
- KEY& curKey = table->key_info[active_index];
-
- for (partsInUse = 0; partsInUse < curKey.key_parts, key - keyBegin < key_len; ++partsInUse)
- {
- Field* field = curKey.key_part[partsInUse].field;
- if ((curKey.key_part[partsInUse].null_bit) &&
- (char*)key[0])
- {
- if (field->flags & AUTO_INCREMENT_FLAG)
- {
- table->status = STATUS_NOT_FOUND;
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
- else
- {
- nullKeyMap[partsInUse] = __NULL_VALUE_EBCDIC;
- }
- }
- else
- {
- nullKeyMap[partsInUse] = __NOT_NULL_VALUE_EBCDIC;
- convertMySQLtoDB2(field,
- db2Table->db2Field(field->field_index),
- db2KeyBufPtr,
- (uchar*)key+((curKey.key_part[partsInUse].null_bit)? 1 : 0) ); // + (curKey.key_parts+7) / 8);
- }
-
- db2KeyBufPtr += db2Table->db2Field(field->field_index).getByteLengthInRecord();
- key += curKey.key_part[partsInUse].store_length;
- }
-
- keyLen = db2KeyBufPtr - (char*)keyBuf.ptr();
-
- DBUG_PRINT("ha_ibmdb2i::index_read", ("find_flag: %d", find_flag));
-
- char readDirection = QMY_NEXT;
-
- switch (find_flag)
- {
- case HA_READ_AFTER_KEY:
- doInitialRead(QMY_AFTER_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_BEFORE_KEY:
- doInitialRead(QMY_BEFORE_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_KEY_OR_NEXT:
- doInitialRead(QMY_AFTER_OR_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_KEY_OR_PREV:
- DBUG_ASSERT(0); // This function is unused
- doInitialRead(QMY_BEFORE_OR_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_PREFIX_LAST_OR_PREV:
- doInitialRead(QMY_LAST_PREVIOUS, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- readDirection = QMY_PREVIOUS;
- break;
- case HA_READ_PREFIX_LAST:
- doInitialRead(QMY_PREFIX_LAST, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- readDirection = QMY_PREVIOUS;
- break;
- case HA_READ_KEY_EXACT:
- doInitialRead(QMY_EQUAL, estimatedRows, keyBuf.ptr(), keyLen, partsInUse);
- break;
- default:
- DBUG_ASSERT(0);
- return HA_ERR_GENERIC;
- break;
- }
-
- ha_statistic_increment(&SSV::ha_read_key_count);
- rc = readFromBuffer(buf, readDirection);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_next(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_next");
- ha_statistic_increment(&SSV::ha_read_next_count);
-
- int rc = readFromBuffer(buf, QMY_NEXT);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_next_same(uchar *buf, const uchar *key, uint keylen)
-{
- DBUG_ENTER("ha_ibmdb2i::index_next_same");
- ha_statistic_increment(&SSV::ha_read_next_count);
-
- int rc = readFromBuffer(buf, QMY_NEXT_EQUAL);
-
- if (rc == HA_ERR_KEY_NOT_FOUND)
- {
- rc = HA_ERR_END_OF_FILE;
- }
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-int ha_ibmdb2i::index_read_last(uchar * buf, const uchar * key, uint key_len)
-{
- DBUG_ENTER("ha_ibmdb2i::index_read_last");
- DBUG_RETURN(index_read(buf, key, key_len, HA_READ_PREFIX_LAST));
-}
-
-
-
-int ha_ibmdb2i::index_prev(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_prev");
- ha_statistic_increment(&SSV::ha_read_prev_count);
-
- int rc = readFromBuffer(buf, QMY_PREVIOUS);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_first(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_first");
-
- if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc);
-
- int rc = prepReadBuffer(DEFAULT_MAX_ROWS_TO_BUFFER,
- db2Table->indexFile(active_index),
- readAccessIntent);
-
- if (rc == 0)
- {
- doInitialRead(QMY_FIRST, DEFAULT_MAX_ROWS_TO_BUFFER);
- ha_statistic_increment(&SSV::ha_read_first_count);
- rc = readFromBuffer(buf, QMY_NEXT);
- }
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_last(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_last");
-
- if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc);
-
- int rc = prepReadBuffer(DEFAULT_MAX_ROWS_TO_BUFFER,
- db2Table->indexFile(active_index),
- readAccessIntent);
-
- if (rc == 0)
- {
- doInitialRead(QMY_LAST, DEFAULT_MAX_ROWS_TO_BUFFER);
- ha_statistic_increment(&SSV::ha_read_last_count);
- rc = readFromBuffer(buf, QMY_PREVIOUS);
- }
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::rnd_init(bool scan)
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_init");
-
- int& rc = last_rnd_init_rc;
- rc = 0;
-
- tweakReadSet();
- invalidDataFound=false;
-
- uint32 rowsToBlockOnRead;
-
- if (!scan)
- {
- rowsToBlockOnRead = 1;
- }
- else
- {
- rowsToBlockOnRead = DEFAULT_MAX_ROWS_TO_BUFFER;
- }
-
- rc = useDataFile();
-
- if (!rc)
- {
-// THD* thd = ha_thd();
-// if (accessIntent == QMY_UPDATABLE &&
-// thd_tx_isolation(thd) == ISO_REPEATABLE_READ &&
-// !THDVAR(thd, transaction_unsafe))
-// {
-// readAccessIntent = QMY_READ_ONLY;
-// }
-// else
-// {
- readAccessIntent = accessIntent;
-// }
-
- rc = prepReadBuffer(rowsToBlockOnRead, db2Table->dataFile(), readAccessIntent);
-
- if (!rc && accessIntent != QMY_READ_ONLY)
- rc = prepWriteBuffer(1, db2Table->dataFile());
-
- if (!rc && scan)
- doInitialRead(QMY_FIRST, rowsToBlockOnRead);
-
- if (rc)
- releaseDataFile();
- }
-
- rrnAssocHandle= 0;
-
- DBUG_RETURN(0); // MySQL sometimes does not check the return code, causing
- // an assert in ha_rnd_end later on if we return a non-zero
- // value here.
-}
-
-int ha_ibmdb2i::rnd_end()
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_end");
-
- warnIfInvalidData();
- if (likely(activeReadBuf))
- activeReadBuf->endRead();
- if (last_rnd_init_rc == 0)
- releaseActiveHandle();
- last_rnd_init_rc = 0;
- DBUG_RETURN(0);
-}
-
-
-int32 ha_ibmdb2i::mungeDB2row(uchar* record, const char* dataPtr, const char* nullMapPtr, bool skipLOBs)
-{
- DBUG_ASSERT(dataPtr);
-
- my_bitmap_map *old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
- my_bitmap_map *old_read_map;
-
- if (unlikely(readAllColumns))
- old_read_map = tmp_use_all_columns(table, table->read_set);
-
- resetCharacterConversionBuffers();
-
- my_ptrdiff_t old_ptr= (my_ptrdiff_t) (record - table->record[0]);
- int fieldIndex = 0;
- for (Field **field = table->field; *field; ++field, ++fieldIndex)
- {
- if (unlikely(old_ptr))
- (*field)->move_field_offset(old_ptr);
- if (nullMapPtr[fieldIndex] == __NULL_VALUE_EBCDIC ||
- (!bitmap_is_set(table->read_set, fieldIndex)) ||
- (skipLOBs && db2Table->db2Field(fieldIndex).isBlob()))
- {
- (*field)->set_null();
- }
- else
- {
- (*field)->set_notnull();
- convertDB2toMySQL(db2Table->db2Field(fieldIndex), *field, dataPtr);
- }
- if (unlikely(old_ptr))
- (*field)->move_field_offset(-old_ptr);
-
- }
-
- if (unlikely(readAllColumns))
- tmp_restore_column_map(table->read_set, old_read_map);
- dbug_tmp_restore_column_map(table->write_set, old_write_map);
-
- return 0;
-}
-
-
-int ha_ibmdb2i::rnd_next(uchar *buf)
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_next");
-
- if (unlikely(last_rnd_init_rc)) DBUG_RETURN(last_rnd_init_rc);
- ha_statistic_increment(&SSV::ha_read_rnd_next_count);
-
- int rc;
-
- rc = readFromBuffer(buf, QMY_NEXT);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-void ha_ibmdb2i::position(const uchar *record)
-{
- DBUG_ENTER("ha_ibmdb2i::position");
- my_store_ptr(ref, ref_length, currentRRN);
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos)
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_pos");
- if (unlikely(last_rnd_init_rc)) DBUG_RETURN( last_rnd_init_rc);
- ha_statistic_increment(&SSV::ha_read_rnd_count);
-
- currentRRN = my_get_ptr(pos, ref_length);
-
- tweakReadSet();
-
- int rc = 0;
-
- if (rrnAssocHandle &&
- (activeHandle != rrnAssocHandle))
- {
- if (activeHandle) releaseActiveHandle();
- rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle);
- }
-
- if (likely(rc == 0))
- {
- rc = prepReadBuffer(1, getFileForActiveHandle(), accessIntent);
-
- if (likely(rc == 0) && accessIntent == QMY_UPDATABLE)
- rc = prepWriteBuffer(1, getFileForActiveHandle());
-
- if (likely(rc == 0))
- {
- rc = db2i_ileBridge::getBridgeForThread()->readByRRN(activeHandle,
- activeReadBuf->ptr(),
- currentRRN,
- accessIntent,
- getCommitLevel());
-
- if (likely(rc == 0))
- {
- rrnAssocHandle = activeHandle;
- const char* readBuf = activeReadBuf->getRowN(0);
- rc = mungeDB2row(buf, readBuf, readBuf + activeReadBuf->getRowNullOffset(), false);
- releaseRowNeeded = TRUE;
- }
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::info(uint flag)
-{
- DBUG_ENTER("ha_ibmdb2i::info");
-
- uint16 infoRequested = 0;
- ValidatedPointer<char> rowKeySpcPtr; // Space pointer passed to DB2
- uint32 rowKeySpcLen; // Length of space passed to DB2
- THD* thd = ha_thd();
- int command = thd_sql_command(thd);
-
- if (flag & HA_STATUS_AUTO)
- stats.auto_increment_value = (ulonglong) 0;
-
- if (flag & HA_STATUS_ERRKEY)
- {
- errkey = lastDupKeyID;
- my_store_ptr(dup_ref, ref_length, lastDupKeyRRN);
- }
-
- if (flag & HA_STATUS_TIME)
- {
- if ((flag & HA_STATUS_NO_LOCK) &&
- ibmdb2i_assume_exclusive_use &&
- share &&
- (share->cachedStats.isInited(lastModTime)))
- stats.update_time = share->cachedStats.getUpdateTime();
- else
- infoRequested |= lastModTime;
- }
-
- if (flag & HA_STATUS_CONST)
- {
- stats.block_size=4096;
- infoRequested |= createTime;
-
- if (table->s->keys)
- {
- infoRequested |= rowsPerKey;
- rowKeySpcLen = (table->s->keys) * MAX_DB2_KEY_PARTS * sizeof(uint64);
- rowKeySpcPtr.alloc(rowKeySpcLen);
- memset(rowKeySpcPtr, 0, rowKeySpcLen); // Clear the allocated space
- }
- }
-
- if (flag & HA_STATUS_VARIABLE)
- {
- if ((flag & HA_STATUS_NO_LOCK) &&
- (command != SQLCOM_SHOW_TABLE_STATUS) &&
- ibmdb2i_assume_exclusive_use &&
- share &&
- (share->cachedStats.isInited(rowCount | deletedRowCount | meanRowLen | ioCount)) &&
- (share->cachedStats.getRowCount() >= 2))
- {
- stats.records = share->cachedStats.getRowCount();
- stats.deleted = share->cachedStats.getDelRowCount();
- stats.mean_rec_length = share->cachedStats.getMeanLength();
- stats.data_file_length = share->cachedStats.getAugmentedDataLength();
- }
- else
- {
- infoRequested |= rowCount | deletedRowCount | meanRowLen;
- if (command == SQLCOM_SHOW_TABLE_STATUS)
- infoRequested |= objLength;
- else
- infoRequested |= ioCount;
- }
- }
-
- int rc = 0;
-
- if (infoRequested)
- {
- DBUG_PRINT("ha_ibmdb2i::info",("Retrieving fresh stats %d", flag));
-
- initBridge(thd);
- rc = bridge()->retrieveTableInfo((dataHandle ? dataHandle : db2Table->dataFile()->getMasterDefnHandle()),
- infoRequested,
- stats,
- rowKeySpcPtr);
-
- if (!rc)
- {
- if ((flag & HA_STATUS_VARIABLE) &&
- (command != SQLCOM_SHOW_TABLE_STATUS))
- stats.data_file_length = stats.data_file_length * IO_SIZE;
-
- if ((ibmdb2i_assume_exclusive_use) &&
- (share) &&
- (command != SQLCOM_SHOW_TABLE_STATUS))
- {
- if (flag & HA_STATUS_VARIABLE)
- {
- share->cachedStats.cacheRowCount(stats.records);
- share->cachedStats.cacheDelRowCount(stats.deleted);
- share->cachedStats.cacheMeanLength(stats.mean_rec_length);
- share->cachedStats.cacheAugmentedDataLength(stats.data_file_length);
- }
-
- if (flag & HA_STATUS_TIME)
- {
- share->cachedStats.cacheUpdateTime(stats.update_time);
- }
- }
-
- if (flag & HA_STATUS_CONST)
- {
- ulong i; // Loop counter for indexes
- ulong j; // Loop counter for key parts
- RowKey* rowKeyPtr; // Pointer to 'number of unique rows' array for this index
-
- rowKeyPtr = (RowKey_t*)(void*)rowKeySpcPtr; // Address first array of DB2 row counts
- for (i = 0; i < table->s->keys; i++) // Do for each index, including primary
- {
- for (j = 0; j < table->key_info[i].key_parts; j++)
- {
- table->key_info[i].rec_per_key[j]= rowKeyPtr->RowKeyArray[j];
- }
- rowKeyPtr = rowKeyPtr + 1; // Address next array of DB2 row counts
- }
- }
- }
- else if (rc == HA_ERR_LOCK_WAIT_TIMEOUT && share)
- {
- // If we couldn't retrieve the info because the object was locked,
- // we'll do our best by returning the most recently cached data.
- if ((infoRequested & rowCount) &&
- share->cachedStats.isInited(rowCount))
- stats.records = share->cachedStats.getRowCount();
- if ((infoRequested & deletedRowCount) &&
- share->cachedStats.isInited(deletedRowCount))
- stats.deleted = share->cachedStats.getDelRowCount();
- if ((infoRequested & meanRowLen) &&
- share->cachedStats.isInited(meanRowLen))
- stats.mean_rec_length = share->cachedStats.getMeanLength();
- if ((infoRequested & lastModTime) &&
- share->cachedStats.isInited(lastModTime))
- stats.update_time = share->cachedStats.getUpdateTime();
-
- rc = 0;
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-
-ha_rows ha_ibmdb2i::records()
-{
- DBUG_ENTER("ha_ibmdb2i::records");
- int rc;
- rc = bridge()->retrieveTableInfo((dataHandle ? dataHandle : db2Table->dataFile()->getMasterDefnHandle()),
- rowCount,
- stats);
-
- if (unlikely(rc))
- {
- if (rc == HA_ERR_LOCK_WAIT_TIMEOUT &&
- share &&
- (share->cachedStats.isInited(rowCount)))
- DBUG_RETURN(share->cachedStats.getRowCount());
- else
- DBUG_RETURN(HA_POS_ERROR);
- }
- else if (share)
- {
- share->cachedStats.cacheRowCount(stats.records);
- }
-
- DBUG_RETURN(stats.records);
-}
-
-
-int ha_ibmdb2i::extra(enum ha_extra_function operation)
-{
- DBUG_ENTER("ha_ibmdb2i::extra");
-
- switch(operation)
- {
- // Can these first five flags be replaced by attending to HA_EXTRA_WRITE_CACHE?
- case HA_EXTRA_NO_IGNORE_DUP_KEY:
- case HA_EXTRA_WRITE_CANNOT_REPLACE:
- {
- returnDupKeysImmediately = false;
- onDupUpdate = false;
- }
- break;
- case HA_EXTRA_INSERT_WITH_UPDATE:
- {
- returnDupKeysImmediately = true;
- onDupUpdate = true;
- }
- break;
- case HA_EXTRA_IGNORE_DUP_KEY:
- case HA_EXTRA_WRITE_CAN_REPLACE:
- returnDupKeysImmediately = true;
- break;
- case HA_EXTRA_FLUSH_CACHE:
- if (outstanding_start_bulk_insert)
- finishBulkInsert();
- break;
- }
-
-
- DBUG_RETURN(0);
-}
-
-/**
- @brief
- The DB2 storage engine will ignore a MySQL generated value and will generate
- a new value in SLIC. We arbitrarily set first_value to 1, and set the
- interval to infinity for better performance on multi-row inserts.
-*/
-void ha_ibmdb2i::get_auto_increment(ulonglong offset, ulonglong increment,
- ulonglong nb_desired_values,
- ulonglong *first_value,
- ulonglong *nb_reserved_values)
-{
- DBUG_ENTER("ha_ibmdb2i::get_auto_increment");
- *first_value= 1;
- *nb_reserved_values= ULONGLONG_MAX;
-}
-
-
-
-void ha_ibmdb2i::update_create_info(HA_CREATE_INFO *create_info)
-{
- DBUG_ENTER("ha_ibmdb2i::update_create_info");
-
- if ((!(create_info->used_fields & HA_CREATE_USED_AUTO)) &&
- (table->found_next_number_field != NULL))
- {
- initBridge();
-
- create_info->auto_increment_value= 1;
-
- ha_rows rowCount = records();
-
- if (rowCount == 0)
- {
- create_info->auto_increment_value = db2Table->getStartId();
- DBUG_VOID_RETURN;
- }
- else if (rowCount == HA_POS_ERROR)
- {
- DBUG_VOID_RETURN;
- }
-
- getNextIdVal(&create_info->auto_increment_value);
- }
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::getNextIdVal(ulonglong *value)
-{
- DBUG_ENTER("ha_ibmdb2i::getNextIdVal");
-
- char queryBuffer[MAX_DB2_COLNAME_LENGTH + MAX_DB2_QUALIFIEDNAME_LENGTH + 64];
- strcpy(queryBuffer, " SELECT CAST(MAX( ");
- convertMySQLNameToDB2Name(table->found_next_number_field->field_name,
- strend(queryBuffer),
- MAX_DB2_COLNAME_LENGTH+1);
- strcat(queryBuffer, ") AS BIGINT) FROM ");
- db2Table->getDB2QualifiedName(strend(queryBuffer));
- DBUG_ASSERT(strlen(queryBuffer) < sizeof(queryBuffer));
-
- SqlStatementStream sqlStream(queryBuffer);
- DBUG_PRINT("ha_ibmdb2i::getNextIdVal", ("Sent to DB2: %s",queryBuffer));
-
- int rc = 0;
- FILE_HANDLE fileHandle2;
- uint32 db2RowDataLen2;
- rc = bridge()->prepOpen(sqlStream.getPtrToData(),
- &fileHandle2,
- &db2RowDataLen2);
- if (likely(rc == 0))
- {
- IOReadBuffer rowBuffer(1, db2RowDataLen2);
- rc = bridge()->read(fileHandle2,
- rowBuffer.ptr(),
- QMY_READ_ONLY,
- QMY_NONE,
- QMY_FIRST);
-
- if (likely(rc == 0))
- {
- /* This check is here for the case where the table is not empty,
- but the auto_increment starting value has been changed since
- the last record was written. */
-
- longlong maxIdVal = *(longlong*)(rowBuffer.getRowN(0));
- if ((maxIdVal + 1) > db2Table->getStartId())
- *value = maxIdVal + 1;
- else
- *value = db2Table->getStartId();
- }
-
- bridge()->deallocateFile(fileHandle2);
- }
- DBUG_RETURN(rc);
-}
-
-
-/*
- Updates index cardinalities.
-*/
-int ha_ibmdb2i::analyze(THD* thd, HA_CHECK_OPT *check_opt)
-{
- DBUG_ENTER("ha_ibmdb2i::analyze");
- info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
- DBUG_RETURN(0);
-}
-
-int ha_ibmdb2i::optimize(THD* thd, HA_CHECK_OPT *check_opt)
-{
- DBUG_ENTER("ha_ibmdb2i::optimize");
-
- initBridge(thd);
-
- if (unlikely(records() == 0))
- DBUG_RETURN(0); // DB2 doesn't like to reorganize a table with no data.
-
- quiesceAllFileHandles();
-
- int32 rc = bridge()->optimizeTable(db2Table->dataFile()->getMasterDefnHandle());
- info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- @brief
- Determines if an ALTER TABLE is allowed to switch the storage engine
- for this table. If the table has a foreign key or is referenced by a
- foreign key, then it cannot be switched.
-*/
-bool ha_ibmdb2i::can_switch_engines(void)
-/*=================================*/
-{
- DBUG_ENTER("ha_ibmdb2i::can_switch_engines");
-
- int rc = 0;
- FILE_HANDLE queryFile = 0;
- uint32 resultRowLen;
- uint count = 0;
- bool can_switch = FALSE; // 1 if changing storage engine is allowed
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- String query(256);
- query.append(STRING_WITH_LEN(" SELECT COUNT(*) FROM SYSIBM.SQLFOREIGNKEYS WHERE ((PKTABLE_SCHEM = '"));
- query.append(libName+1, strlen(libName)-2); // Remove quotes from parent schema name
- query.append(STRING_WITH_LEN("' AND PKTABLE_NAME = '"));
- query.append(fileName+1,strlen(fileName)-2); // Remove quotes from file name
- query.append(STRING_WITH_LEN("') OR (FKTABLE_SCHEM = '"));
- query.append(libName+1,strlen(libName)-2); // Remove quotes from child schema
- query.append(STRING_WITH_LEN("' AND FKTABLE_NAME = '"));
- query.append(fileName+1,strlen(fileName)-2); // Remove quotes from child name
- query.append(STRING_WITH_LEN("'))"));
-
- SqlStatementStream sqlStream(query);
-
- rc = bridge()->prepOpen(sqlStream.getPtrToData(),
- &queryFile,
- &resultRowLen);
- if (rc == 0)
- {
- IOReadBuffer rowBuffer(1, resultRowLen);
-
- rc = bridge()->read(queryFile,
- rowBuffer.ptr(),
- QMY_READ_ONLY,
- QMY_NONE,
- QMY_FIRST);
- if (!rc)
- {
- count = *(uint*)(rowBuffer.getRowN(0));
- if (count == 0)
- can_switch = TRUE;
- }
-
- bridge()->deallocateFile(queryFile);
- }
- DBUG_RETURN(can_switch);
-}
-
-
-
-bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info,
- uint table_changes)
-{
- DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data");
- uint i;
- /* Check that auto_increment value and field definitions were
- not changed. */
- if ((info->used_fields & HA_CREATE_USED_AUTO &&
- info->auto_increment_value != 0) ||
- table_changes != IS_EQUAL_YES)
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- /* Check if any fields were renamed. */
- for (i= 0; i < table->s->fields; i++)
- {
- Field *field= table->field[i];
- if (field->flags & FIELD_IS_RENAMED)
- {
- DBUG_PRINT("info", ("Field has been renamed, copy table"));
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- }
- }
- DBUG_RETURN(COMPATIBLE_DATA_YES);
-}
-
-int ha_ibmdb2i::reset_auto_increment(ulonglong value)
- {
- DBUG_ENTER("ha_ibmdb2i::reset_auto_increment");
-
- int rc = 0;
-
- quiesceAllFileHandles();
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- String query(512);
- query.append(STRING_WITH_LEN(" ALTER TABLE "));
- query.append(libName);
- query.append('.');
- query.append(fileName);
- query.append(STRING_WITH_LEN(" ALTER COLUMN "));
- char colName[MAX_DB2_COLNAME_LENGTH+1];
- convertMySQLNameToDB2Name(table->found_next_number_field->field_name,
- colName,
- sizeof(colName));
- query.append(colName);
-
- char restart_value[22];
- CHARSET_INFO *cs= &my_charset_bin;
- uint len = (uint)(cs->cset->longlong10_to_str)(cs,restart_value,sizeof(restart_value), 10, value);
- restart_value[len] = 0;
-
- query.append(STRING_WITH_LEN(" RESTART WITH "));
- query.append(restart_value);
-
- SqlStatementStream sqlStream(query);
- DBUG_PRINT("ha_ibmdb2i::reset_auto_increment", ("Sent to DB2: %s",query.c_ptr()));
-
- rc = db2i_ileBridge::getBridgeForThread()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- QMY_NONE, //getCommitLevel(),
- FALSE,
- FALSE,
- TRUE, //FALSE,
- dataHandle);
- if (rc == 0)
- db2Table->updateStartId(value);
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- @brief
- This function receives an error code that was previously set by the handler.
- It returns to MySQL the error string associated with that error.
-*/
-bool ha_ibmdb2i::get_error_message(int error, String *buf)
-{
- DBUG_ENTER("ha_ibmdb2i::get_error_message");
- if ((error >= DB2I_FIRST_ERR && error <= DB2I_LAST_ERR) ||
- (error >= QMY_ERR_MIN && error <= QMY_ERR_MAX))
- {
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(ha_thd());
- char* errMsg = bridge->getErrorStorage();
- buf->copy(errMsg, strlen(errMsg),system_charset_info);
- bridge->freeErrorStorage();
- }
- DBUG_RETURN(FALSE);
-}
-
-
-int ha_ibmdb2i::delete_all_rows()
-{
- DBUG_ENTER("ha_ibmdb2i::delete_all_rows");
- int rc = 0;
- char queryBuffer[MAX_DB2_QUALIFIEDNAME_LENGTH + 64];
- strcpy(queryBuffer, " DELETE FROM ");
- db2Table->getDB2QualifiedName(strend(queryBuffer));
- DBUG_ASSERT(strlen(queryBuffer) < sizeof(queryBuffer));
-
- SqlStatementStream sqlStream(queryBuffer);
- DBUG_PRINT("ha_ibmdb2i::delete_all_rows", ("Sent to DB2: %s",queryBuffer));
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- getCommitLevel(),
- false,
- false,
- true,
- dataHandle);
-
- /* If this method was called on behalf of a TRUNCATE TABLE statement, and if */
- /* the table has an auto_increment field, then reset the starting value for */
- /* the auto_increment field to 1.
- */
- if (rc == 0 && thd_sql_command(ha_thd()) == SQLCOM_TRUNCATE &&
- table->found_next_number_field )
- rc = reset_auto_increment(1);
-
- invalidateCachedStats();
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::external_lock(THD *thd, int lock_type)
-{
- int rc = 0;
-
- DBUG_ENTER("ha_ibmdb2i::external_lock");
- DBUG_PRINT("ha_ibmdb2i::external_lock",("Lock type: %d", lock_type));
-
- if (lock_type == F_RDLCK)
- accessIntent = QMY_READ_ONLY;
- else if (lock_type == F_WRLCK)
- accessIntent = QMY_UPDATABLE;
-
- initBridge(thd);
- int command = thd_sql_command(thd);
-
- if (!THDVAR(thd,transaction_unsafe))
- {
- if (lock_type != F_UNLCK)
- {
- if (autoCommitIsOn(thd) == QMY_YES)
- {
- trans_register_ha(thd, FALSE, ibmdb2i_hton);
- }
- else
- {
- trans_register_ha(thd, TRUE, ibmdb2i_hton);
- if (likely(command != SQLCOM_CREATE_TABLE))
- {
- trans_register_ha(thd, FALSE, ibmdb2i_hton);
- bridge()->beginStmtTx();
- }
- }
- }
- }
-
- if (command == SQLCOM_LOCK_TABLES ||
- command == SQLCOM_ALTER_TABLE ||
- command == SQLCOM_UNLOCK_TABLES ||
- (accessIntent == QMY_UPDATABLE &&
- (command == SQLCOM_UPDATE ||
- command == SQLCOM_UPDATE_MULTI ||
- command == SQLCOM_DELETE ||
- command == SQLCOM_DELETE_MULTI ||
- command == SQLCOM_REPLACE ||
- command == SQLCOM_REPLACE_SELECT) &&
- getCommitLevel(thd) == QMY_NONE))
- {
- char action;
- char type;
- if (lock_type == F_UNLCK)
- {
- action = QMY_UNLOCK;
- type = accessIntent == QMY_READ_ONLY ? QMY_LSRD : QMY_LENR;
- }
- else
- {
- action = QMY_LOCK;
- type = lock_type == F_RDLCK ? QMY_LSRD : QMY_LENR;
- }
-
- DBUG_PRINT("ha_ibmdb2i::external_lock",("%socking table", action==QMY_LOCK ? "L" : "Unl"));
-
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
-
- rc = bridge()->lockObj(dataHandle,
- 0,
- action,
- type,
- (command == SQLCOM_LOCK_TABLES ? QMY_NO : QMY_YES));
-
- }
-
- // Cache this away so we don't have to access it on each row operation
- cachedZeroDateOption = (enum_ZeroDate)THDVAR(thd, compat_opt_allow_zero_date_vals);
-
- DBUG_RETURN(rc);
-}
-
-
-THR_LOCK_DATA **ha_ibmdb2i::store_lock(THD *thd,
- THR_LOCK_DATA **to,
- enum thr_lock_type lock_type)
-{
- if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
- {
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) && !(thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES))
- lock_type= TL_WRITE_ALLOW_WRITE;
- lock.type=lock_type;
- }
- *to++= &lock;
- return to;
-}
-
-
-int ha_ibmdb2i::delete_table(const char *name)
-{
- DBUG_ENTER("ha_ibmdb2i::delete_table");
- THD* thd = ha_thd();
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(thd);
-
- char db2Name[MAX_DB2_QUALIFIEDNAME_LENGTH];
- db2i_table::getDB2QualifiedNameFromPath(name, db2Name);
-
- String query(128);
- query.append(STRING_WITH_LEN(" DROP TABLE "));
- query.append(db2Name);
-
- if (thd_sql_command(thd) == SQLCOM_DROP_TABLE &&
- thd->lex->drop_mode == DROP_RESTRICT)
- query.append(STRING_WITH_LEN(" RESTRICT "));
- DBUG_PRINT("ha_ibmdb2i::delete_table", ("Sent to DB2: %s",query.c_ptr()));
-
- SqlStatementStream sqlStream(query);
-
- db2i_table::getDB2LibNameFromPath(name, db2Name);
- bool isTemporary = (strcmp(db2Name, DB2I_TEMP_TABLE_SCHEMA) == 0 ? TRUE : FALSE);
-
- int rc = bridge->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- (isTemporary ? QMY_NONE : getCommitLevel(thd)),
- FALSE,
- FALSE,
- isTemporary);
-
- if (rc == HA_ERR_NO_SUCH_TABLE)
- {
- warning(thd, DB2I_ERR_TABLE_NOT_FOUND, name);
- rc = 0;
- }
-
- if (rc == 0)
- {
- db2i_table::deleteAssocFiles(name);
- }
-
- FILE_HANDLE savedHandle = bridge->findAndRemovePreservedHandle(name, &share);
- while (savedHandle)
- {
- bridge->deallocateFile(savedHandle, TRUE);
- DBUG_ASSERT(share);
- if (free_share(share))
- share = NULL;
- savedHandle = bridge->findAndRemovePreservedHandle(name, &share);
- }
-
- my_errno = rc;
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::rename_table(const char * from, const char * to)
-{
- DBUG_ENTER("ha_ibmdb2i::rename_table ");
-
- char db2FromFileName[MAX_DB2_FILENAME_LENGTH + 1];
- char db2ToFileName[MAX_DB2_FILENAME_LENGTH+1];
- char db2FromLibName[MAX_DB2_SCHEMANAME_LENGTH+1];
- char db2ToLibName[MAX_DB2_SCHEMANAME_LENGTH+1];
-
- db2i_table::getDB2LibNameFromPath(from, db2FromLibName);
- db2i_table::getDB2LibNameFromPath(to, db2ToLibName);
-
- if (strcmp(db2FromLibName, db2ToLibName) != 0 )
- {
- getErrTxt(DB2I_ERR_RENAME_MOVE,from,to);
- DBUG_RETURN(DB2I_ERR_RENAME_MOVE);
- }
-
- db2i_table::getDB2FileNameFromPath(from, db2FromFileName, db2i_table::ASCII_NATIVE);
- db2i_table::getDB2FileNameFromPath(to, db2ToFileName);
-
- char escapedFromFileName[2 * MAX_DB2_FILENAME_LENGTH + 1];
-
- uint o = 0;
- uint i = 1;
- do
- {
- escapedFromFileName[o++] = db2FromFileName[i];
- if (db2FromFileName[i] == '+')
- escapedFromFileName[o++] = '+';
- } while (db2FromFileName[++i]);
- escapedFromFileName[o-1] = 0;
-
-
- int rc = 0;
-
- char queryBuffer[sizeof(db2FromLibName) + 2 * sizeof(db2FromFileName) + 256];
- SafeString selectQuery(queryBuffer, sizeof(queryBuffer));
- selectQuery.strncat(STRING_WITH_LEN("SELECT CAST(INDEX_NAME AS VARCHAR(128) CCSID 1208) FROM QSYS2.SYSINDEXES WHERE INDEX_NAME LIKE '%+_+_+_%"));
- selectQuery.strcat(escapedFromFileName);
- selectQuery.strncat(STRING_WITH_LEN("' ESCAPE '+' AND TABLE_NAME='"));
- selectQuery.strncat(db2FromFileName+1, strlen(db2FromFileName)-2);
- selectQuery.strncat(STRING_WITH_LEN("' AND TABLE_SCHEMA='"));
- selectQuery.strncat(db2FromLibName+1, strlen(db2FromLibName)-2);
- selectQuery.strcat('\'');
- DBUG_ASSERT(!selectQuery.overflowed());
-
- SqlStatementStream indexQuery(selectQuery.ptr());
-
- FILE_HANDLE queryFile = 0;
- uint32 resultRowLen;
-
- initBridge();
- rc = bridge()->prepOpen(indexQuery.getPtrToData(),
- &queryFile,
- &resultRowLen);
-
- if (unlikely(rc))
- DBUG_RETURN(rc);
-
- IOReadBuffer rowBuffer(1, resultRowLen);
-
- int tableNameLen = strlen(db2FromFileName) - 2;
-
- SqlStatementStream renameQuery(64);
- String query;
- while (rc == 0)
- {
- query.length(0);
-
- rc = bridge()->read(queryFile,
- rowBuffer.ptr(),
- QMY_READ_ONLY,
- QMY_NONE,
- QMY_NEXT);
-
- if (!rc)
- {
- const char* rowData = rowBuffer.getRowN(0);
- char indexFileName[MAX_DB2_FILENAME_LENGTH];
- memset(indexFileName, 0, sizeof(indexFileName));
-
- uint16 fileNameLen = *(uint16*)(rowData);
- strncpy(indexFileName, rowData + sizeof(uint16), fileNameLen);
-
- int bytesToRetain = fileNameLen - tableNameLen;
- if (bytesToRetain <= 0)
- /* We can't handle index names in which the MySQL index name and
- the table name together are longer than the max index name. */
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- DBUG_RETURN(DB2I_ERR_INVALID_NAME);
- }
- char indexName[MAX_DB2_FILENAME_LENGTH];
- memset(indexName, 0, sizeof(indexName));
-
- strncpy(indexName,
- indexFileName,
- bytesToRetain);
-
- char db2IndexName[MAX_DB2_FILENAME_LENGTH+1];
-
- convertMySQLNameToDB2Name(indexFileName, db2IndexName, sizeof(db2IndexName));
-
- query.append(STRING_WITH_LEN("RENAME INDEX "));
- query.append(db2FromLibName);
- query.append('.');
- query.append(db2IndexName);
- query.append(STRING_WITH_LEN(" TO "));
- if (db2i_table::appendQualifiedIndexFileName(indexName, db2ToFileName, query, db2i_table::ASCII_SQL, typeNone) == -1)
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- DBUG_RETURN(DB2I_ERR_INVALID_NAME );
- }
- renameQuery.addStatement(query);
- DBUG_PRINT("ha_ibmdb2i::rename_table", ("Sent to DB2: %s",query.c_ptr_safe()));
- }
- }
-
-
- if (queryFile)
- bridge()->deallocateFile(queryFile);
-
- if (rc != HA_ERR_END_OF_FILE)
- DBUG_RETURN(rc);
-
- char db2Name[MAX_DB2_QUALIFIEDNAME_LENGTH];
-
- /* Rename the table */
- query.length(0);
- query.append(STRING_WITH_LEN(" RENAME TABLE "));
- db2i_table::getDB2QualifiedNameFromPath(from, db2Name);
- query.append(db2Name);
- query.append(STRING_WITH_LEN(" TO "));
- query.append(db2ToFileName);
- DBUG_PRINT("ha_ibmdb2i::rename_table", ("Sent to DB2: %s",query.c_ptr_safe()));
- renameQuery.addStatement(query);
- rc = bridge()->execSQL(renameQuery.getPtrToData(),
- renameQuery.getStatementCount(),
- getCommitLevel());
-
- if (!rc)
- db2i_table::renameAssocFiles(from, to);
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
- HA_CREATE_INFO *create_info)
-{
- DBUG_ENTER("ha_ibmdb2i::create");
-
- int rc;
- char fileSortSequence[11] = "*HEX";
- char fileSortSequenceLibrary[11] = "";
- char fileSortSequenceType = ' ';
- char libName[MAX_DB2_SCHEMANAME_LENGTH+1];
- char fileName[MAX_DB2_FILENAME_LENGTH+1];
- char colName[MAX_DB2_COLNAME_LENGTH+1];
- bool isTemporary;
- ulong auto_inc_value;
-
- db2i_table::getDB2LibNameFromPath(name, libName);
- db2i_table::getDB2FileNameFromPath(name, fileName);
-
- if (osVersion.v < 6)
- {
- if (strlen(libName) >
- MAX_DB2_V5R4_LIBNAME_LENGTH + (isOrdinaryIdentifier(libName) ? 2 : 0))
- {
- getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V5R4_LIBNAME_LENGTH);
- DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA);
- }
- }
- else if (strlen(libName) > MAX_DB2_V6R1_LIBNAME_LENGTH)
- {
- getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V6R1_LIBNAME_LENGTH);
- DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA);
- }
-
- String query(256);
-
- if (strcmp(libName, DB2I_TEMP_TABLE_SCHEMA))
- {
- query.append(STRING_WITH_LEN("CREATE TABLE "));
- query.append(libName);
- query.append('.');
- query.append(fileName);
- isTemporary = FALSE;
- }
- else
- {
- query.append(STRING_WITH_LEN("DECLARE GLOBAL TEMPORARY TABLE "));
- query.append(fileName);
- isTemporary = TRUE;
- }
- query.append(STRING_WITH_LEN(" ("));
-
- THD* thd = ha_thd();
- enum_TimeFormat timeFormat = (enum_TimeFormat)(THDVAR(thd, compat_opt_time_as_duration));
- enum_YearFormat yearFormat = (enum_YearFormat)(THDVAR(thd, compat_opt_year_as_int));
- enum_BlobMapping blobMapping = (enum_BlobMapping)(THDVAR(thd, compat_opt_blob_cols));
- enum_ZeroDate zeroDate = (enum_ZeroDate)(THDVAR(thd, compat_opt_allow_zero_date_vals));
- bool propagateDefaults = THDVAR(thd, propagate_default_col_vals);
-
- Field **field;
- for (field= table_arg->field; *field; field++)
- {
- if ( field != table_arg->field ) // Not the first one
- query.append(STRING_WITH_LEN(" , "));
-
- if (!convertMySQLNameToDB2Name((*field)->field_name, colName, sizeof(colName)))
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"field",(*field)->field_name);
- DBUG_RETURN(DB2I_ERR_INVALID_NAME );
- }
-
- query.append(colName);
- query.append(' ');
-
- if (rc = getFieldTypeMapping(*field,
- query,
- timeFormat,
- blobMapping,
- zeroDate,
- propagateDefaults,
- yearFormat))
- DBUG_RETURN(rc);
-
- if ( (*field)->flags & NOT_NULL_FLAG )
- {
- query.append(STRING_WITH_LEN(" NOT NULL "));
- }
- if ( (*field)->flags & AUTO_INCREMENT_FLAG )
- {
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- if (table_arg->part_info)
- {
- getErrTxt(DB2I_ERR_PART_AUTOINC);
- DBUG_RETURN(DB2I_ERR_PART_AUTOINC);
- }
-#endif
- query.append(STRING_WITH_LEN(" GENERATED BY DEFAULT AS IDENTITY ") );
- if (create_info->auto_increment_value != 0)
- {
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Set the starting
- value for the auto_increment column. */
- char stringValue[22];
- CHARSET_INFO *cs= &my_charset_bin;
- uint len = (uint)(cs->cset->longlong10_to_str)(cs,stringValue,sizeof(stringValue), 10, create_info->auto_increment_value);
- stringValue[len] = 0;
- query.append(STRING_WITH_LEN(" (START WITH "));
- query.append(stringValue);
-
- uint64 maxValue=maxValueForField(*field);
-
- if (maxValue)
- {
- len = (uint)(cs->cset->longlong10_to_str)(cs,stringValue,sizeof(stringValue), 10, maxValue);
- stringValue[len] = 0;
- query.append(STRING_WITH_LEN(" MAXVALUE "));
- query.append(stringValue);
- }
-
- query.append(STRING_WITH_LEN(") "));
- }
-
- }
- }
-
- String fieldDefinition(128);
-
- if (table_arg->s->primary_key != MAX_KEY && !isTemporary)
- {
- query.append(STRING_WITH_LEN(", PRIMARY KEY "));
- rc = buildIndexFieldList(fieldDefinition,
- table_arg->key_info[table_arg->s->primary_key],
- true,
- &fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
- if (rc) DBUG_RETURN(rc);
- query.append(fieldDefinition);
- }
-
- rc = buildDB2ConstraintString(thd->lex,
- query,
- name,
- table_arg->field,
- &fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
- if (rc) DBUG_RETURN (rc);
-
- query.append(STRING_WITH_LEN(" ) "));
-
- if (isTemporary)
- query.append(STRING_WITH_LEN(" ON COMMIT PRESERVE ROWS "));
-
- if (create_info->alias)
- generateAndAppendRCDFMT(create_info->alias, query);
- else if (((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name)
- generateAndAppendRCDFMT((char*)((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name, query);
-
- DBUG_PRINT("ha_ibmdb2i::create", ("Sent to DB2: %s",query.c_ptr()));
- SqlStatementStream sqlStream(query.length());
- sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary);
-
- if (table_arg->s->primary_key != MAX_KEY &&
- !isTemporary &&
- (THDVAR(thd, create_index_option)==1) &&
- (fileSortSequenceType != 'B') &&
- (fileSortSequenceType != ' '))
- {
- rc = generateShadowIndex(sqlStream,
- table_arg->key_info[table_arg->s->primary_key],
- libName,
- fileName,
- fieldDefinition);
- if (rc) DBUG_RETURN(rc);
- }
- for (uint i = 0; i < table_arg->s->keys; ++i)
- {
- if (i != table_arg->s->primary_key || isTemporary)
- {
- rc = buildCreateIndexStatement(sqlStream,
- table_arg->key_info[i],
- false,
- libName,
- fileName);
- if (rc) DBUG_RETURN (rc);
- }
- }
-
- bool noCommit = isTemporary || ((!autoCommitIsOn(thd)) && (thd_sql_command(thd) == SQLCOM_ALTER_TABLE));
-
- initBridge();
-
-// if (THDVAR(thd, discovery_mode) == 1)
-// bridge()->expectErrors(QMY_ERR_TABLE_EXISTS);
-
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- (isTemporary ? QMY_NONE : getCommitLevel(thd)),
- TRUE,
- FALSE,
- noCommit );
-
- if (unlikely(rc == QMY_ERR_MSGID) &&
- memcmp(bridge()->getErrorMsgID(), DB2I_SQL0350, 7) == 0)
- {
- my_error(ER_BLOB_USED_AS_KEY, MYF(0), "*unknown*");
- rc = ER_BLOB_USED_AS_KEY;
- }
-/* else if (unlikely(rc == QMY_ERR_TABLE_EXISTS) &&
- THDVAR(thd, discovery_mode) == 1)
- {
- db2i_table* temp = new db2i_table(table_arg->s, name);
- int32 rc = temp->fastInitForCreate(name);
- delete temp;
-
- if (!rc)
- warning(thd, DB2I_ERR_WARN_CREATE_DISCOVER);
-
- DBUG_RETURN(rc);
- }
-*/
-
- if (!rc && !isTemporary)
- {
- db2i_table* temp = new db2i_table(table_arg->s, name);
- rc = temp->fastInitForCreate(name);
- delete temp;
- if (rc)
- delete_table(name);
- }
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- @brief
- Add an index on-line to a table. This method is called on behalf of
- a CREATE INDEX or ALTER TABLE statement.
- It is implemented via a composed DDL statement passed to DB2.
-*/
-int ha_ibmdb2i::add_index(TABLE *table_arg,
- KEY *key_info,
- uint num_of_keys)
-{
- DBUG_ENTER("ha_ibmdb2i::add_index");
-
- int rc;
- SqlStatementStream sqlStream(256);
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- quiesceAllFileHandles();
-
- uint primaryKey = MAX_KEY;
- if (table_arg->s->primary_key >= MAX_KEY && !db2Table->isTemporary())
- {
- for (int i = 0; i < num_of_keys; ++i)
- {
- if (strcmp(key_info[i].name, "PRIMARY") == 0)
- {
- primaryKey = i;
- break;
- }
- else if (primaryKey == MAX_KEY &&
- key_info[i].flags & HA_NOSAME)
- {
- primaryKey = i;
- for (int j=0 ; j < key_info[i].key_parts ;j++)
- {
- uint fieldnr= key_info[i].key_part[j].fieldnr;
- if (table_arg->s->field[fieldnr]->null_ptr ||
- table_arg->s->field[fieldnr]->key_length() !=
- key_info[i].key_part[j].length)
- {
- primaryKey = MAX_KEY;
- break;
- }
- }
- }
- }
- }
-
-
- for (int i = 0; i < num_of_keys; ++i)
- {
- KEY& curKey= key_info[i];
- rc = buildCreateIndexStatement(sqlStream,
- curKey,
- (i == primaryKey),
- libName,
- fileName);
- if (rc) DBUG_RETURN (rc);
- }
-
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- getCommitLevel(),
- FALSE,
- FALSE,
- FALSE,
- dataHandle);
-
- /* Handle the case where a unique index is being created but an error occurs
- because the file contains duplicate key values. */
- if (rc == ER_DUP_ENTRY)
- print_keydup_error(MAX_KEY,ER(ER_DUP_ENTRY_WITH_KEY_NAME));
-
- DBUG_RETURN(rc);
-}
-
-/**
- @brief
- Drop an index on-line from a table. This method is called on behalf of
- a DROP INDEX or ALTER TABLE statement.
- It is implemented via a composed DDL statement passed to DB2.
-*/
-int ha_ibmdb2i::prepare_drop_index(TABLE *table_arg,
- uint *key_num, uint num_of_keys)
-{
- DBUG_ENTER("ha_ibmdb2i::prepare_drop_index");
- int rc;
- int i = 0;
- String query(64);
- SqlStatementStream sqlStream(64 * num_of_keys);
- SqlStatementStream shadowStream(64 * num_of_keys);
-
- quiesceAllFileHandles();
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- while (i < num_of_keys)
- {
- query.length(0);
- DBUG_PRINT("info", ("ha_ibmdb2i::prepare_drop_index %u", key_num[i]));
- KEY& curKey= table_arg->key_info[key_num[i]];
- if (key_num[i] == table->s->primary_key && !db2Table->isTemporary())
- {
- query.append(STRING_WITH_LEN("ALTER TABLE "));
- query.append(libName);
- query.append(STRING_WITH_LEN("."));
- query.append(fileName);
- query.append(STRING_WITH_LEN(" DROP PRIMARY KEY"));
- }
- else
- {
- query.append(STRING_WITH_LEN("DROP INDEX "));
- query.append(libName);
- query.append(STRING_WITH_LEN("."));
- db2i_table::appendQualifiedIndexFileName(curKey.name, fileName, query);
- }
- DBUG_PRINT("ha_ibmdb2i::prepare_drop_index", ("Sent to DB2: %s",query.c_ptr_safe()));
- sqlStream.addStatement(query);
-
- query.length(0);
- query.append(STRING_WITH_LEN("DROP INDEX "));
- query.append(libName);
- query.append(STRING_WITH_LEN("."));
- db2i_table::appendQualifiedIndexFileName(curKey.name, fileName, query, db2i_table::ASCII_SQL, typeHex);
-
- DBUG_PRINT("ha_ibmdb2i::prepare_drop_index", ("Sent to DB2: %s",query.c_ptr_safe()));
- shadowStream.addStatement(query);
-
- ++i;
- }
-
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- getCommitLevel(),
- FALSE,
- FALSE,
- FALSE,
- dataHandle);
-
- if (rc == 0)
- bridge()->execSQL(shadowStream.getPtrToData(),
- shadowStream.getStatementCount(),
- getCommitLevel());
-
- DBUG_RETURN(rc);
-}
-
-
-void
-ha_ibmdb2i::unlock_row()
-{
- DBUG_ENTER("ha_ibmdb2i::unlock_row");
- DBUG_VOID_RETURN;
-}
-
-int
-ha_ibmdb2i::index_end()
-{
- DBUG_ENTER("ha_ibmdb2i::index_end");
- warnIfInvalidData();
- last_index_init_rc = 0;
- if (likely(activeReadBuf))
- activeReadBuf->endRead();
- if (likely(!last_index_init_rc))
- releaseIndexFile(active_index);
- active_index= MAX_KEY;
- DBUG_RETURN (0);
-}
-
-int ha_ibmdb2i::doCommit(handlerton *hton, THD *thd, bool all)
-{
- if (!THDVAR(thd, transaction_unsafe))
- {
- if (all || autoCommitIsOn(thd))
- {
- DBUG_PRINT("ha_ibmdb2i::doCommit",("Committing all"));
- return (db2i_ileBridge::getBridgeForThread(thd)->commitmentControl(QMY_COMMIT));
- }
- else
- {
- DBUG_PRINT("ha_ibmdb2i::doCommit",("Committing stmt"));
- return (db2i_ileBridge::getBridgeForThread(thd)->commitStmtTx());
- }
- }
-
- return (0);
-}
-
-
-int ha_ibmdb2i::doRollback(handlerton *hton, THD *thd, bool all)
-{
- if (!THDVAR(thd,transaction_unsafe))
- {
- if (all || autoCommitIsOn(thd))
- {
- DBUG_PRINT("ha_ibmdb2i::doRollback",("Rolling back all"));
- return ( db2i_ileBridge::getBridgeForThread(thd)->commitmentControl(QMY_ROLLBACK));
- }
- else
- {
- DBUG_PRINT("ha_ibmdb2i::doRollback",("Rolling back stmt"));
- return (db2i_ileBridge::getBridgeForThread(thd)->rollbackStmtTx());
- }
- }
- return (0);
-}
-
-
-void ha_ibmdb2i::start_bulk_insert(ha_rows rows)
-{
- DBUG_ENTER("ha_ibmdb2i::start_bulk_insert");
- DBUG_PRINT("ha_ibmdb2i::start_bulk_insert",("Rows hinted %d", rows));
- int rc;
- THD* thd = ha_thd();
- int command = thd_sql_command(thd);
-
- if (db2Table->hasBlobs() ||
- (command == SQLCOM_REPLACE || command == SQLCOM_REPLACE_SELECT))
- rows = 1;
- else if (rows == 0)
- rows = DEFAULT_MAX_ROWS_TO_BUFFER; // Shoot the moon
-
- // If we're doing a multi-row insert, binlogging is active, and the table has an
- // auto_increment column, then we'll attempt to lock the file while we perform a 'fast path' blocked
- // insert. If we can't get the lock, then we'll do a row-by-row 'slow path' insert instead. The reason is
- // because the MI generates the auto_increment (identity value), and if we can't lock the file,
- // then we can't predetermine what that value will be for insertion into the MySQL write buffer.
-
- if ((rows > 1) && // Multi-row insert
- (thd->options & OPTION_BIN_LOG) && // Binlogging is on
- (table->found_next_number_field)) // Table has an auto_increment column
- {
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
-
- rc = bridge()->lockObj(dataHandle, 1, QMY_LOCK, QMY_LEAR, QMY_YES);
- if (rc==0) // Got the lock
- {
- autoIncLockAcquired = TRUE;
- got_auto_inc_values = FALSE;
- }
- else // Didn't get the lock
- rows = 1; // No problem, but don't block inserts
- }
-
- if (activeHandle == 0)
- {
- last_start_bulk_insert_rc = useDataFile();
- if (last_start_bulk_insert_rc == 0)
- last_start_bulk_insert_rc = prepWriteBuffer(rows, db2Table->dataFile());
- }
-
- if (last_start_bulk_insert_rc == 0)
- outstanding_start_bulk_insert = true;
- else
- {
- if (autoIncLockAcquired == TRUE)
- {
- bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LEAR, QMY_YES);
- autoIncLockAcquired = FALSE;
- }
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::end_bulk_insert()
-{
- DBUG_ENTER("ha_ibmdb2i::end_bulk_insert");
- int rc = 0;
-
- if (outstanding_start_bulk_insert)
- {
- rc = finishBulkInsert();
- }
-
- my_errno = rc;
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead, const db2i_file* file, char intent)
-{
- DBUG_ENTER("ha_ibmdb2i::prepReadBuffer");
- DBUG_ASSERT(rowsToRead > 0);
-
- THD* thd = ha_thd();
- char cmtLvl = getCommitLevel(thd);
-
- const db2i_file::RowFormat* format;
- int rc = file->obtainRowFormat(activeHandle, intent, cmtLvl, &format);
-
- if (unlikely(rc)) DBUG_RETURN(rc);
-
- if (lobFieldsRequested())
- {
- forceSingleRowRead = true;
- rowsToRead = 1;
- }
-
- rowsToRead = min(stats.records+1,min(rowsToRead, DEFAULT_MAX_ROWS_TO_BUFFER));
-
- uint bufSize = min((format->readRowLen * rowsToRead), THDVAR(thd, max_read_buffer_size));
- multiRowReadBuf.allocBuf(format->readRowLen, format->readRowNullOffset, bufSize);
- activeReadBuf = &multiRowReadBuf;
-
- if (db2Table->hasBlobs())
- {
- if (!blobReadBuffers)
- blobReadBuffers = new BlobCollection(db2Table, THDVAR(thd, lob_alloc_size));
- rc = prepareReadBufferForLobs();
- if (rc) DBUG_RETURN(rc);
- }
-
-// if (accessIntent == QMY_UPDATABLE &&
-// thd_tx_isolation(thd) == ISO_REPEATABLE_READ &&
-// !THDVAR(thd, transaction_unsafe))
-// activeReadBuf->update(QMY_READ_ONLY, &releaseRowNeeded, QMY_REPEATABLE_READ);
-// else
- activeReadBuf->update(intent, &releaseRowNeeded, cmtLvl);
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::prepWriteBuffer(ha_rows rowsToWrite, const db2i_file* file)
-{
- DBUG_ENTER("ha_ibmdb2i::prepWriteBuffer");
- DBUG_ASSERT(accessIntent == QMY_UPDATABLE && rowsToWrite > 0);
-
- const db2i_file::RowFormat* format;
- int rc = file->obtainRowFormat(activeHandle,
- QMY_UPDATABLE,
- getCommitLevel(ha_thd()),
- &format);
-
- if (unlikely(rc)) DBUG_RETURN(rc);
-
- rowsToWrite = min(rowsToWrite, DEFAULT_MAX_ROWS_TO_BUFFER);
-
- uint bufSize = min((format->writeRowLen * rowsToWrite), THDVAR(ha_thd(), max_write_buffer_size));
- multiRowWriteBuf.allocBuf(format->writeRowLen, format->writeRowNullOffset, bufSize);
- activeWriteBuf = &multiRowWriteBuf;
-
- if (!blobWriteBuffers && db2Table->hasBlobs())
- {
- blobWriteBuffers = new ValidatedPointer<char>[db2Table->getBlobCount()];
- }
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::flushWrite(FILE_HANDLE fileHandle, uchar* buf )
-{
- DBUG_ENTER("ha_ibmdb2i::flushWrite");
- int rc;
- int64 generatedIdValue = 0;
- bool IdValueWasGenerated = FALSE;
- char* lastDupKeyNamePtr = NULL;
- uint32 lastDupKeyNameLen = 0;
- int loopCnt = 0;
- bool retry_dup = FALSE;
-
- while (loopCnt == 0 || retry_dup == TRUE)
- {
- rc = bridge()->writeRows(fileHandle,
- activeWriteBuf->ptr(),
- getCommitLevel(),
- &generatedIdValue,
- &IdValueWasGenerated,
- &lastDupKeyRRN,
- &lastDupKeyNamePtr,
- &lastDupKeyNameLen,
- &incrementByValue);
- loopCnt++;
- retry_dup = FALSE;
- invalidateCachedStats();
- if (lastDupKeyNameLen)
- {
- rrnAssocHandle = fileHandle;
-
- int command = thd_sql_command(ha_thd());
-
- if (command == SQLCOM_REPLACE ||
- command == SQLCOM_REPLACE_SELECT)
- lastDupKeyID = 0;
- else
- {
- lastDupKeyID = getKeyFromName(lastDupKeyNamePtr, lastDupKeyNameLen);
-
- if (likely(lastDupKeyID != MAX_KEY))
- {
- uint16 failedRow = activeWriteBuf->rowsWritten()+1;
-
- if (buf && (failedRow != activeWriteBuf->rowCount()))
- {
- const char* badRow = activeWriteBuf->getRowN(failedRow-1);
- bool savedReadAllColumns = readAllColumns;
- readAllColumns = true;
- mungeDB2row(buf,
- badRow,
- badRow + activeWriteBuf->getRowNullOffset(),
- true);
- readAllColumns = savedReadAllColumns;
-
- if (table->found_next_number_field)
- {
- table->next_number_field->store(next_identity_value - (incrementByValue * (activeWriteBuf->rowCount() - (failedRow - 1))));
- }
- }
-
- if (default_identity_value && // Table has ID colm and generating a value
- (!autoIncLockAcquired || !got_auto_inc_values) &&
- // Writing first or only row in block
- loopCnt == 1 && // Didn't already retry
- lastDupKeyID == table->s->next_number_index) // Autoinc column is in failed index
- {
- if (alterStartWith() == 0) // Reset next Identity value to max+1
- retry_dup = TRUE; // Rtry the write operation
- }
- }
- else
- {
- char unknownIndex[MAX_DB2_FILENAME_LENGTH+1];
- convFromEbcdic(lastDupKeyNamePtr, unknownIndex, min(lastDupKeyNameLen, MAX_DB2_FILENAME_LENGTH));
- unknownIndex[min(lastDupKeyNameLen, MAX_DB2_FILENAME_LENGTH)] = 0;
- getErrTxt(DB2I_ERR_UNKNOWN_IDX, unknownIndex);
- }
- }
- }
- }
-
- if ((rc == 0 || rc == HA_ERR_FOUND_DUPP_KEY)
- && default_identity_value && IdValueWasGenerated &&
- (!autoIncLockAcquired || !got_auto_inc_values))
- {
- /* Save the generated identity value for the MySQL last_insert_id() function. */
- insert_id_for_cur_row = generatedIdValue;
-
- /* Store the value into MySQL's buf for row-based replication
- or for an 'on duplicate key update' clause. */
- table->next_number_field->store((longlong) generatedIdValue, TRUE);
- if (autoIncLockAcquired)
- {
- got_auto_inc_values = TRUE;
- next_identity_value = generatedIdValue + incrementByValue;
- }
- }
- else
- {
- if (!autoIncLockAcquired) // Don't overlay value for first row of a block
- insert_id_for_cur_row = 0;
- }
-
-
- activeWriteBuf->resetAfterWrite();
- DBUG_RETURN(rc);
-}
-
-int ha_ibmdb2i::alterStartWith()
-{
- DBUG_ENTER("ha_ibmdb2i::alterStartWith");
- int rc = 0;
- ulonglong nextIdVal;
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
- if (!rc) {rc = bridge()->lockObj(dataHandle, 1, QMY_LOCK, QMY_LENR, QMY_YES);}
- if (!rc)
- {
- rc = getNextIdVal(&nextIdVal);
- if (!rc) {rc = reset_auto_increment(nextIdVal);}
- bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LENR, QMY_YES);
- }
- DBUG_RETURN(rc);
-}
-
-bool ha_ibmdb2i::lobFieldsRequested()
-{
- if (!db2Table->hasBlobs())
- {
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("No LOBs"));
- return (false);
- }
-
- if (readAllColumns)
- {
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("All cols requested"));
- return (true);
- }
-
- for (int i = 0; i < db2Table->getBlobCount(); ++i)
- {
- if (bitmap_is_set(table->read_set, db2Table->blobFields[i]))
- {
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("LOB requested"));
- return (true);
- }
- }
-
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("No LOBs requested"));
- return (false);
-}
-
-
-int ha_ibmdb2i::prepareReadBufferForLobs()
-{
- DBUG_ENTER("ha_ibmdb2i::prepareReadBufferForLobs");
- DBUG_ASSERT(db2Table->hasBlobs());
-
- uint32 activeLobFields = 0;
- DB2LobField* lobField;
- uint16 blobCount = db2Table->getBlobCount();
-
- char* readBuf = activeReadBuf->getRowN(0);
-
- for (int i = 0; i < blobCount; ++i)
- {
- int fieldID = db2Table->blobFields[i];
- DB2Field& db2Field = db2Table->db2Field(fieldID);
- lobField = db2Field.asBlobField(readBuf);
- if (readAllColumns ||
- bitmap_is_set(table->read_set, fieldID))
- {
- lobField->dataHandle = (ILEMemHandle)blobReadBuffers->getBufferPtr(fieldID);
- activeLobFields++;
- }
- else
- {
- lobField->dataHandle = NULL;
- }
- }
-
- if (activeLobFields == 0)
- {
- for (int i = 0; i < blobCount; ++i)
- {
- DB2Field& db2Field = db2Table->db2Field(db2Table->blobFields[i]);
- uint16 offset = db2Field.getBufferOffset() + db2Field.calcBlobPad();
-
- for (int r = 1; r < activeReadBuf->getRowCapacity(); ++r)
- {
- lobField = (DB2LobField*)(activeReadBuf->getRowN(r) + offset);
- lobField->dataHandle = NULL;
- }
- }
- }
-
- activeReadBuf->setRowsToProcess((activeLobFields ? 1 : activeReadBuf->getRowCapacity()));
- int rc = bridge()->objectOverride(activeHandle,
- activeReadBuf->ptr(),
- activeReadBuf->getRowLength());
- DBUG_RETURN(rc);
-}
-
-
-uint32 ha_ibmdb2i::adjustLobBuffersForRead()
-{
- DBUG_ENTER("ha_ibmdb2i::adjustLobBuffersForRead");
-
- char* readBuf = activeReadBuf->getRowN(0);
-
- for (int i = 0; i < db2Table->getBlobCount(); ++i)
- {
- DB2Field& db2Field = db2Table->db2Field(db2Table->blobFields[i]);
- DB2LobField* lobField = db2Field.asBlobField(readBuf);
- if (readAllColumns ||
- bitmap_is_set(table->read_set, db2Table->blobFields[i]))
- {
- lobField->dataHandle = (ILEMemHandle)blobReadBuffers->reallocBuffer(db2Table->blobFields[i], lobField->length);
-
- if (lobField->dataHandle == NULL)
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
- else
- {
- lobField->dataHandle = 0;
- }
- }
-
- int32 rc = bridge()->objectOverride(activeHandle,
- activeReadBuf->ptr());
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::reset()
-{
- DBUG_ENTER("ha_ibmdb2i::reset");
-
- if (outstanding_start_bulk_insert)
- {
- finishBulkInsert();
- }
-
- if (activeHandle != 0)
- {
- releaseActiveHandle();
- }
-
- cleanupBuffers();
-
- db2i_ileBridge::getBridgeForThread(ha_thd())->freeErrorStorage();
-
- last_rnd_init_rc = last_index_init_rc = last_start_bulk_insert_rc = 0;
-
- returnDupKeysImmediately = false;
- onDupUpdate = false;
- forceSingleRowRead = false;
-
-#ifndef DBUG_OFF
- cachedBridge=NULL;
-#endif
-
- DBUG_RETURN(0);
-}
-
-
-int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream,
- KEY& key,
- bool isPrimary,
- const char* db2LibName,
- const char* db2FileName)
-{
- DBUG_ENTER("ha_ibmdb2i::buildCreateIndexStatement");
-
- char fileSortSequence[11] = "*HEX";
- char fileSortSequenceLibrary[11] = "";
- char fileSortSequenceType = ' ';
- String query(256);
- query.length(0);
- int rc = 0;
-
- if (isPrimary)
- {
- query.append(STRING_WITH_LEN("ALTER TABLE "));
- query.append(db2LibName);
- query.append('.');
- query.append(db2FileName);
- query.append(STRING_WITH_LEN(" ADD PRIMARY KEY "));
- }
- else
- {
- query.append(STRING_WITH_LEN("CREATE"));
-
- if (key.flags & HA_NOSAME)
- query.append(STRING_WITH_LEN(" UNIQUE WHERE NOT NULL"));
-
- query.append(STRING_WITH_LEN(" INDEX "));
-
- query.append(db2LibName);
- query.append('.');
- if (db2i_table::appendQualifiedIndexFileName(key.name, db2FileName, query))
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- DBUG_RETURN(DB2I_ERR_INVALID_NAME );
- }
-
- query.append(STRING_WITH_LEN(" ON "));
-
- query.append(db2LibName);
- query.append('.');
- query.append(db2FileName);
- }
-
- String fieldDefinition(128);
- rc = buildIndexFieldList(fieldDefinition,
- key,
- isPrimary,
- &fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
-
- if (rc) DBUG_RETURN(rc);
-
- query.append(fieldDefinition);
-
- if ((THDVAR(ha_thd(), create_index_option)==1) &&
- (fileSortSequenceType != 'B') &&
- (fileSortSequenceType != ' '))
- {
- rc = generateShadowIndex(sqlStream,
- key,
- db2LibName,
- db2FileName,
- fieldDefinition);
- if (rc) DBUG_RETURN(rc);
- }
-
- DBUG_PRINT("ha_ibmdb2i::buildCreateIndexStatement", ("Sent to DB2: %s",query.c_ptr_safe()));
- sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary);
-
- DBUG_RETURN(0);
-}
-
-/**
- Generate the SQL syntax for the list of fields to be assigned to the
- specified key. The corresponding sort sequence is also calculated.
-
- @param[out] appendHere The string to receive the generated SQL
- @param key The key to evaluate
- @param isPrimary True if this is being generated on behalf of the primary key
- @param[out] fileSortSequenceType The type of the associated sort sequence
- @param[out] fileSortSequence The name of the associated sort sequence
- @param[out] fileSortSequenceLibrary The library of the associated sort sequence
-
- @return 0 if successful; error value otherwise
-*/
-int32 ha_ibmdb2i::buildIndexFieldList(String& appendHere,
- const KEY& key,
- bool isPrimary,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary)
-{
- DBUG_ENTER("ha_ibmdb2i::buildIndexFieldList");
- appendHere.append(STRING_WITH_LEN(" ( "));
- for (int j = 0; j < key.key_parts; ++j)
- {
- char colName[MAX_DB2_COLNAME_LENGTH+1];
- if (j != 0)
- {
- appendHere.append(STRING_WITH_LEN(" , "));
- }
-
- KEY_PART_INFO& kpi = key.key_part[j];
- Field* field = kpi.field;
-
- convertMySQLNameToDB2Name(field->field_name,
- colName,
- sizeof(colName));
- appendHere.append(colName);
-
- int32 rc;
- rc = updateAssociatedSortSequence(field->charset(),
- fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
- if (rc) DBUG_RETURN (rc);
- }
-
- appendHere.append(STRING_WITH_LEN(" ) "));
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Generate an SQL statement that defines a *HEX sorted index to implement
- the ibmdb2i_create_index.
-
- @param[out] stream The stream to append the generated statement to
- @param key The key to evaluate
- @param[out] libName The library containg the table
- @param[out] fileName The DB2-compatible name of the table
- @param[out] fieldDefinition The list of the fields in the index, in SQL syntax
-
- @return 0 if successful; error value otherwise
-*/
-int32 ha_ibmdb2i::generateShadowIndex(SqlStatementStream& stream,
- const KEY& key,
- const char* libName,
- const char* fileName,
- const String& fieldDefinition)
-{
- String shadowQuery(256);
- shadowQuery.length(0);
- shadowQuery.append(STRING_WITH_LEN("CREATE INDEX "));
- shadowQuery.append(libName);
- shadowQuery.append('.');
- if (db2i_table::appendQualifiedIndexFileName(key.name, fileName, shadowQuery, db2i_table::ASCII_SQL, typeHex))
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- return DB2I_ERR_INVALID_NAME;
- }
- shadowQuery.append(STRING_WITH_LEN(" ON "));
- shadowQuery.append(libName);
- shadowQuery.append('.');
- shadowQuery.append(fileName);
- shadowQuery.append(fieldDefinition);
- DBUG_PRINT("ha_ibmdb2i::generateShadowIndex", ("Sent to DB2: %s",shadowQuery.c_ptr_safe()));
- stream.addStatement(shadowQuery,"*HEX","QSYS");
- return 0;
-}
-
-
-void ha_ibmdb2i::doInitialRead(char orientation,
- uint32 rowsToBuffer,
- ILEMemHandle key,
- int keyLength,
- int keyParts)
-{
- DBUG_ENTER("ha_ibmdb2i::doInitialRead");
-
- if (forceSingleRowRead)
- rowsToBuffer = 1;
- else
- rowsToBuffer = min(rowsToBuffer, activeReadBuf->getRowCapacity());
-
- activeReadBuf->newReadRequest(activeHandle,
- orientation,
- rowsToBuffer,
- THDVAR(ha_thd(), async_enabled),
- key,
- keyLength,
- keyParts);
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::start_stmt(THD *thd, thr_lock_type lock_type)
-{
- DBUG_ENTER("ha_ibmdb2i::start_stmt");
- initBridge(thd);
- if (!THDVAR(thd, transaction_unsafe))
- {
- trans_register_ha(thd, FALSE, ibmdb2i_hton);
-
- if (!autoCommitIsOn(thd))
- {
- bridge()->beginStmtTx();
- }
- }
-
- DBUG_RETURN(0);
-}
-
-int32 ha_ibmdb2i::handleLOBReadOverflow()
-{
- DBUG_ENTER("ha_ibmdb2i::handleLOBReadOverflow");
- DBUG_ASSERT(db2Table->hasBlobs() && (activeReadBuf->getRowCapacity() == 1));
-
- int32 rc = adjustLobBuffersForRead();
-
- if (!rc)
- {
- activeReadBuf->rewind();
- rc = bridge()->expectErrors(QMY_ERR_END_OF_BLOCK)
- ->read(activeHandle,
- activeReadBuf->ptr(),
- accessIntent,
- getCommitLevel(),
- QMY_SAME);
- releaseRowNeeded = TRUE;
-
- }
- DBUG_RETURN(rc);
-}
-
-
-int32 ha_ibmdb2i::finishBulkInsert()
-{
- int32 rc = 0;
-
- if (activeWriteBuf->rowCount() && activeHandle)
- rc = flushWrite(activeHandle, table->record[0]);
-
- if (activeHandle)
- releaseActiveHandle();
-
- if (autoIncLockAcquired == TRUE)
- {
- // We could check the return code on the unlock, but beware not
- // to overlay the return code from the flushwrite or we will mask
- // duplicate key errors..
- bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LEAR, QMY_YES);
- autoIncLockAcquired = FALSE;
- }
- outstanding_start_bulk_insert = false;
- multiRowWriteBuf.freeBuf();
- last_start_bulk_insert_rc = 0;
-
- resetCharacterConversionBuffers();
-
- return rc;
-}
-
-int ha_ibmdb2i::getKeyFromName(const char* name, size_t len)
-{
- for (int i = 0; i < table_share->keys; ++i)
- {
- const char* indexName = db2Table->indexFile(i)->getDB2FileName();
- if ((strncmp(name, indexName, len) == 0) &&
- (strlen(indexName) == len))
- {
- return i;
- }
- }
- return MAX_KEY;
-}
-
-/*
-Determine the number of I/O's it takes to read through the table.
- */
-double ha_ibmdb2i::scan_time()
- {
- DBUG_ENTER("ha_ibmdb2i::scan_time");
- DBUG_RETURN(ulonglong2double((stats.data_file_length)/IO_SIZE));
- }
-
-
-/**
- Estimate the number of I/O's it takes to read a set of ranges through
- an index.
-
- @param index
- @param ranges
- @param rows
-
- @return The estimate number of I/Os
-*/
-
-double ha_ibmdb2i::read_time(uint index, uint ranges, ha_rows rows)
-{
- DBUG_ENTER("ha_ibmdb2i::read_time");
- int rc;
- uint64 idxPageCnt = 0;
- double cost;
-
- if (unlikely(rows == HA_POS_ERROR))
- DBUG_RETURN(double(rows) + ranges);
-
- rc = bridge()->retrieveIndexInfo(db2Table->indexFile(index)->getMasterDefnHandle(),
- &idxPageCnt);
- if (!rc)
- {
- if ((idxPageCnt == 1) || // Retrieving rows in requested order or
- (ranges == rows)) // 'Sweep' full records retrieval
- cost = idxPageCnt/4;
- else
- {
- uint64 totalRecords = stats.records + 1;
- double dataPageCount = stats.data_file_length/IO_SIZE;
-
- cost = (rows * dataPageCount / totalRecords) +
- min(idxPageCnt, (log_2(idxPageCnt) * ranges +
- rows * (log_2(idxPageCnt) + log_2(rows) - log_2(totalRecords))));
- }
- }
- else
- {
- cost = rows2double(ranges+rows); // Use default costing
- }
- DBUG_RETURN(cost);
-}
-
-int ha_ibmdb2i::useIndexFile(int idx)
-{
- DBUG_ENTER("ha_ibmdb2i::useIndexFile");
-
- if (activeHandle)
- releaseActiveHandle();
-
- int rc = 0;
-
- if (!indexHandles[idx])
- rc = db2Table->indexFile(idx)->allocateNewInstance(&indexHandles[idx], curConnection);
-
- if (rc == 0)
- {
- activeHandle = indexHandles[idx];
- bumpInUseCounter(1);
- }
-
- DBUG_RETURN(rc);
-}
-
-
-ulong ha_ibmdb2i::index_flags(uint inx, uint part, bool all_parts) const
-{
- return HA_READ_NEXT | HA_READ_PREV | HA_KEYREAD_ONLY | HA_READ_ORDER | HA_READ_RANGE;
-}
-
-
-static struct st_mysql_sys_var* ibmdb2i_system_variables[] = {
- MYSQL_SYSVAR(rdb_name),
- MYSQL_SYSVAR(transaction_unsafe),
- MYSQL_SYSVAR(lob_alloc_size),
- MYSQL_SYSVAR(max_read_buffer_size),
- MYSQL_SYSVAR(max_write_buffer_size),
- MYSQL_SYSVAR(async_enabled),
- MYSQL_SYSVAR(assume_exclusive_use),
- MYSQL_SYSVAR(compat_opt_blob_cols),
- MYSQL_SYSVAR(compat_opt_time_as_duration),
- MYSQL_SYSVAR(compat_opt_allow_zero_date_vals),
- MYSQL_SYSVAR(compat_opt_year_as_int),
- MYSQL_SYSVAR(propagate_default_col_vals),
- MYSQL_SYSVAR(create_index_option),
-// MYSQL_SYSVAR(discovery_mode),
- MYSQL_SYSVAR(system_trace_level),
- NULL
-};
-
-
-struct st_mysql_storage_engine ibmdb2i_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION };
-
-mysql_declare_plugin(ibmdb2i)
-{
- MYSQL_STORAGE_ENGINE_PLUGIN,
- &ibmdb2i_storage_engine,
- "IBMDB2I",
- "The IBM development team in Rochester, Minnesota",
- "IBM DB2 for i Storage Engine",
- PLUGIN_LICENSE_GPL,
- ibmdb2i_init_func, /* Plugin Init */
- ibmdb2i_done_func, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
- NULL, /* status variables */
- ibmdb2i_system_variables, /* system variables */
- NULL /* config options */
-}
-mysql_declare_plugin_end;
diff --git a/storage/ibmdb2i/ha_ibmdb2i.h b/storage/ibmdb2i/ha_ibmdb2i.h
deleted file mode 100644
index b2a43232f2d..00000000000
--- a/storage/ibmdb2i/ha_ibmdb2i.h
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "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 IBM CORPORATION 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.
-*/
-
-/** @file ha_ibmdb2i.h
-
- @brief
-
- @note
-
- @see
-*/
-
-#ifdef USE_PRAGMA_INTERFACE
-#pragma interface /* gcc class implementation */
-#endif
-
-#include "as400_types.h"
-#include "as400_protos.h"
-#include "db2i_global.h"
-#include "db2i_ileBridge.h"
-#include "builtins.h"
-#include "db2i_misc.h"
-#include "db2i_file.h"
-#include "db2i_blobCollection.h"
-#include "db2i_collationSupport.h"
-#include "db2i_validatedPointer.h"
-#include "db2i_ioBuffers.h"
-#include "db2i_errors.h"
-#include "db2i_sqlStatementStream.h"
-
-/** @brief
- IBMDB2I_SHARE is a structure that will be shared among all open handlers.
- It is used to describe the underlying table definition, and it caches
- table statistics.
-*/
-struct IBMDB2I_SHARE {
- char *table_name;
- uint table_name_length,use_count;
- pthread_mutex_t mutex;
- THR_LOCK lock;
-
- db2i_table* db2Table;
-
- class CStats
- {
- public:
- void cacheUpdateTime(time_t time)
- {update_time = time; initFlag |= lastModTime;}
- time_t getUpdateTime() const
- {return update_time;}
- void cacheRowCount(ha_rows rows)
- {records = rows; initFlag |= rowCount;}
- ha_rows getRowCount() const
- {return records;}
- void cacheDelRowCount(ha_rows rows)
- {deleted = rows; initFlag |= deletedRowCount;}
- ha_rows getDelRowCount() const
- {return deleted;}
- void cacheMeanLength(ulong len)
- {mean_rec_length = len; initFlag |= meanRowLen;}
- ulong getMeanLength()
- {return mean_rec_length;}
- void cacheAugmentedDataLength(ulong len)
- {data_file_length = len; initFlag |= ioCount;}
- ulong getAugmentedDataLength()
- {return data_file_length;}
- bool isInited(uint flags)
- {return initFlag & flags;}
- void invalidate(uint flags)
- {initFlag &= ~flags;}
-
- private:
- uint initFlag;
- time_t update_time;
- ha_rows records;
- ha_rows deleted;
- ulong mean_rec_length;
- ulong data_file_length;
- } cachedStats;
-
-};
-
-class ha_ibmdb2i: public handler
-{
- THR_LOCK_DATA lock; ///< MySQL lock
- IBMDB2I_SHARE *share; ///< Shared lock info
-
- // The record we are positioned on, together with the handle used to get
- // i.
- uint32 currentRRN;
- uint32 rrnAssocHandle;
-
- // Dup key values needed by info()
- uint32 lastDupKeyRRN;
- uint32 lastDupKeyID;
-
- bool returnDupKeysImmediately;
-
- // Dup key value need by update()
- bool onDupUpdate;
-
-
- db2i_table* db2Table;
-
- // The file handle of the PF or LF being accessed by the current operation.
- FILE_HANDLE activeHandle;
-
- // The file handle of the underlying PF
- FILE_HANDLE dataHandle;
-
- // Array of file handles belonging to the underlying LFs
- FILE_HANDLE* indexHandles;
-
- // Flag to indicate whether a call needs to be made to unlock a row when
- // a read operation has ended. DB2 will handle row unlocking as we move
- // through rows, but if an operation ends before we reach the end of a file,
- // DB2 needs to know to unlock the last row read.
- bool releaseRowNeeded;
-
- // Pointer to a definition of the layout of the row buffer for the file
- // described by activeHandle
- const db2i_file::RowFormat* activeFormat;
-
- IORowBuffer keyBuf;
- uint32 keyLen;
-
- IOWriteBuffer multiRowWriteBuf;
- IOAsyncReadBuffer multiRowReadBuf;
-
- IOAsyncReadBuffer* activeReadBuf;
- IOWriteBuffer* activeWriteBuf;
-
- BlobCollection* blobReadBuffers; // Dynamically allocated per query and used
- // to manage the buffers used for reading LOBs
- ValidatedPointer<char>* blobWriteBuffers;
-
- // Return codes are not used/honored by rnd_init and start_bulk_insert
- // so we need a way to signal the failure "downstream" to subsequent
- // functions.
- int last_rnd_init_rc;
- int last_index_init_rc;
- int last_start_bulk_insert_rc;
-
- // end_bulk_insert may get called twice for a single start_bulk_insert
- // This is our way to do cleanup only once.
- bool outstanding_start_bulk_insert;
-
- // Auto_increment 'increment by' value needed by write_row()
- uint32 incrementByValue;
- bool default_identity_value;
-
- // Flags and values used during write operations for auto_increment processing
- bool autoIncLockAcquired;
- bool got_auto_inc_values;
- uint64 next_identity_value;
-
- // The access intent indicated by the last external_locks() call.
- // May be either QMY_READ or QMY_UPDATABLE
- char accessIntent;
- char readAccessIntent;
-
- ha_rows* indexReadSizeEstimates;
-
- MEM_ROOT conversionBufferMemroot;
-
- bool forceSingleRowRead;
-
- bool readAllColumns;
-
- bool invalidDataFound;
-
- db2i_ileBridge* cachedBridge;
-
- ValidatedObject<volatile uint32> curConnection;
- uint16 activeReferences;
-
-public:
-
- ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg);
- ~ha_ibmdb2i();
-
- const char *table_type() const { return "IBMDB2I"; }
- const char *index_type(uint inx) { return "RADIX"; }
- const key_map *keys_to_use_for_scanning() { return &key_map_full; }
- const char **bas_ext() const;
-
- ulonglong table_flags() const
- {
- return HA_NULL_IN_KEY | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY |
- HA_PARTIAL_COLUMN_READ |
- HA_DUPLICATE_POS | HA_NO_PREFIX_CHAR_KEYS |
- HA_HAS_RECORDS | HA_BINLOG_ROW_CAPABLE | HA_REQUIRES_KEY_COLUMNS_FOR_DELETE |
- HA_CAN_INDEX_BLOBS;
- }
-
- ulong index_flags(uint inx, uint part, bool all_parts) const;
-
-// Note that we do not implement max_supported_record_length.
-// We'll let create fail accordingly if the row is
-// too long. This allows us to hide the fact that varchars > 32K are being
-// implemented as DB2 LOBs.
-
- uint max_supported_keys() const { return 4000; }
- uint max_supported_key_parts() const { return MAX_DB2_KEY_PARTS; }
- uint max_supported_key_length() const { return 32767; }
- uint max_supported_key_part_length() const { return 32767; }
- double read_time(uint index, uint ranges, ha_rows rows);
- double scan_time();
- int open(const char *name, int mode, uint test_if_locked);
- int close(void);
- int write_row(uchar * buf);
- int update_row(const uchar * old_data, uchar * new_data);
- int delete_row(const uchar * buf);
- int index_init(uint idx, bool sorted);
- int index_read(uchar * buf, const uchar * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_next(uchar * buf);
- int index_read_last(uchar * buf, const uchar * key, uint key_len);
- int index_next_same(uchar *buf, const uchar *key, uint keylen);
- int index_prev(uchar * buf);
- int index_first(uchar * buf);
- int index_last(uchar * buf);
- int rnd_init(bool scan);
- int rnd_end();
- int rnd_next(uchar *buf);
- int rnd_pos(uchar * buf, uchar *pos);
- void position(const uchar *record);
- int info(uint);
- ha_rows records();
- int extra(enum ha_extra_function operation);
- int external_lock(THD *thd, int lock_type);
- int delete_all_rows(void);
- ha_rows records_in_range(uint inx, key_range *min_key,
- key_range *max_key);
- int delete_table(const char *from);
- int rename_table(const char * from, const char * to);
- int create(const char *name, TABLE *form,
- HA_CREATE_INFO *create_info);
- int updateFrm(TABLE *table_def, File file);
- int openTableDef(TABLE *table_def);
- int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys);
- int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys);
- int final_drop_index(TABLE *table_arg) {return 0;}
- void get_auto_increment(ulonglong offset, ulonglong increment,
- ulonglong nb_desired_values,
- ulonglong *first_value,
- ulonglong *nb_reserved_values);
- int reset_auto_increment(ulonglong value);
- void restore_auto_increment(ulonglong prev_insert_id) {return;}
- void update_create_info(HA_CREATE_INFO *create_info);
- int getNextIdVal(ulonglong *value);
- int analyze(THD* thd,HA_CHECK_OPT* check_opt);
- int optimize(THD* thd, HA_CHECK_OPT* check_opt);
- bool can_switch_engines();
- void free_foreign_key_create_info(char* str);
- char* get_foreign_key_create_info();
- int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
- uint referenced_by_foreign_key();
- bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
- virtual bool get_error_message(int error, String *buf);
-
- THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type);
-
- bool low_byte_first() const { return 0; }
- void unlock_row();
- int index_end();
- int reset();
- static int doCommit(handlerton *hton, THD *thd, bool all);
- static int doRollback(handlerton *hton, THD *thd, bool all);
- void start_bulk_insert(ha_rows rows);
- int end_bulk_insert();
- int start_stmt(THD *thd, thr_lock_type lock_type);
-
- void initBridge(THD* thd = NULL)
- {
- if (thd == NULL) thd = ha_thd();
- DBUG_PRINT("ha_ibmdb2i::initBridge",("Initing bridge. Conn ID=%d", thd->thread_id));
- cachedBridge = db2i_ileBridge::getBridgeForThread(thd);
- }
-
- db2i_ileBridge* bridge() {DBUG_ASSERT(cachedBridge); return cachedBridge;}
-
- static uint8 autoCommitIsOn(THD* thd)
- { return (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ? QMY_NO : QMY_YES); }
-
- uint8 getCommitLevel();
- uint8 getCommitLevel(THD* thd);
-
- static int doSavepointSet(THD* thd, char* name)
- {
- return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_SET_SAVEPOINT,
- name);
- }
-
- static int doSavepointRollback(THD* thd, char* name)
- {
- return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_ROLLBACK_SAVEPOINT,
- name);
- }
-
- static int doSavepointRelease(THD* thd, char* name)
- {
- return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_RELEASE_SAVEPOINT,
- name);
- }
-
- // We can't guarantee that the rows we know about when this is called
- // will be the same number of rows that read returns (since DB2 activity
- // may insert additional rows). Therefore, we do as the Federated SE and
- // return the max possible.
- ha_rows estimate_rows_upper_bound()
- {
- return HA_POS_ERROR;
- }
-
-
-private:
-
- enum enum_TimeFormat
- {
- TIME_OF_DAY,
- DURATION
- };
-
- enum enum_BlobMapping
- {
- AS_BLOB,
- AS_VARCHAR
- };
-
- enum enum_ZeroDate
- {
- NO_SUBSTITUTE,
- SUBSTITUTE_0001_01_01
- };
-
- enum enum_YearFormat
- {
- CHAR4,
- SMALLINT
- };
-
- enum_ZeroDate cachedZeroDateOption;
-
- IBMDB2I_SHARE *get_share(const char *table_name, TABLE *table);
- int free_share(IBMDB2I_SHARE *share);
- int32 mungeDB2row(uchar* record, const char* dataPtr, const char* nullMapPtr, bool skipLOBs);
- int prepareRowForWrite(char* data, char* nulls, bool honorIdentCols);
- int prepareReadBufferForLobs();
- int32 prepareWriteBufferForLobs();
- uint32 adjustLobBuffersForRead();
- bool lobFieldsRequested();
- int convertFieldChars(enum_conversionDirection direction,
- uint16 fieldID,
- const char* input,
- char* output,
- size_t ilen,
- size_t olen,
- size_t* outDataLen,
- bool tacitErrors=FALSE,
- size_t* substChars=NULL);
-
- /**
- Fast integer log2 function
- */
- uint64 log_2(uint64 val)
- {
- uint64 exp = 0;
- while( (val >> exp) != 0)
- {
- exp++;
- }
- DBUG_ASSERT(exp-1 == (uint64)log2(val));
- return exp-1;
- }
-
- void bumpInUseCounter(uint16 amount)
- {
- activeReferences += amount;
- DBUG_PRINT("ha_ibmdb2i::bumpInUseCounter", ("activeReferences = %d", activeReferences));
- if (activeReferences)
- curConnection = (uint32)(ha_thd()->thread_id);
- else
- curConnection = 0;
- }
-
-
- int useDataFile()
- {
- DBUG_ENTER("ha_ibmdb2i::useDataFile");
-
- int rc = 0;
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
- else if (activeHandle == dataHandle)
- DBUG_RETURN(0);
-
- DBUG_ASSERT(activeHandle == 0);
-
- if (likely(rc == 0))
- {
- activeHandle = dataHandle;
- bumpInUseCounter(1);
- }
-
- DBUG_RETURN(rc);
- }
-
- void releaseAnyLockedRows()
- {
- if (releaseRowNeeded)
- {
- DBUG_PRINT("ha_ibmdb2i::releaseAnyLockedRows", ("Releasing rows"));
- db2i_ileBridge::getBridgeForThread()->rrlslck(activeHandle, accessIntent);
- releaseRowNeeded = FALSE;
- }
- }
-
-
- void releaseDataFile()
- {
- DBUG_ENTER("ha_ibmdb2i::releaseDataFile");
- releaseAnyLockedRows();
- bumpInUseCounter(-1);
- DBUG_ASSERT((volatile int)activeReferences >= 0);
- activeHandle = 0;
- DBUG_VOID_RETURN;
- }
-
- int useIndexFile(int idx);
-
- void releaseIndexFile(int idx)
- {
- DBUG_ENTER("ha_ibmdb2i::releaseIndexFile");
- releaseAnyLockedRows();
- bumpInUseCounter(-1);
- DBUG_ASSERT((volatile int)activeReferences >= 0);
- activeHandle = 0;
- DBUG_VOID_RETURN;
- }
-
- FILE_HANDLE allocateFileHandle(char* database, char* table, int* activityReference, bool hasBlobs);
-
- int updateBuffers(const db2i_file::RowFormat* format, uint rowsToRead, uint rowsToWrite);
-
- int flushWrite(FILE_HANDLE fileHandle, uchar* buf = NULL);
-
- int alterStartWith();
-
- int buildDB2ConstraintString(LEX* lex,
- String& appendHere,
- const char* database,
- Field** fields,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary);
-
- void releaseWriteBuffer();
-
- void setIndexReadEstimate(uint index, ha_rows rows)
- {
- if (!indexReadSizeEstimates)
- {
- indexReadSizeEstimates = (ha_rows*)my_malloc(sizeof(ha_rows) * table->s->keys, MYF(MY_WME | MY_ZEROFILL));
- }
- indexReadSizeEstimates[index] = rows;
- }
-
- ha_rows getIndexReadEstimate(uint index)
- {
- if (indexReadSizeEstimates)
- return max(indexReadSizeEstimates[index], 1);
-
- return 10000; // Assume index scan if no estimate exists.
- }
-
-
- void quiesceAllFileHandles()
- {
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread();
- if (dataHandle)
- {
- bridge->quiesceFileInstance(dataHandle);
- }
-
- for (int idx = 0; idx < table_share->keys; ++idx)
- {
- if (indexHandles[idx] != 0)
- {
- bridge->quiesceFileInstance(indexHandles[idx]);
- }
- }
- }
-
- int32 buildCreateIndexStatement(SqlStatementStream& sqlStream,
- KEY& key,
- bool isPrimary,
- const char* db2LibName,
- const char* db2FileName);
-
- int32 buildIndexFieldList(String& appendHere,
- const KEY& key,
- bool isPrimary,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary);
-
- // Specify NULL for data when using the data pointed to by field
- int32 convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data = NULL);
-
- int32 convertDB2toMySQL(const DB2Field& db2Field, Field* field, const char* buf);
- int getFieldTypeMapping(Field* field,
- String& mapping,
- enum_TimeFormat timeFormate,
- enum_BlobMapping blobMapping,
- enum_ZeroDate zeroDateHandling,
- bool propagateDefaults,
- enum_YearFormat yearFormat);
-
- int getKeyFromName(const char* name, size_t len);
-
- void releaseActiveHandle()
- {
- if (activeHandle == dataHandle)
- releaseDataFile();
- else
- releaseIndexFile(active_index);
- }
-
-
- int32 finishBulkInsert();
-
- void doInitialRead(char orientation,
- uint32 rowsToBuffer,
- ILEMemHandle key = 0,
- int keyLength = 0,
- int keyParts = 0);
-
-
- int32 readFromBuffer(uchar* destination, char orientation)
- {
- char* row;
- int32 rc = 0;
- row = activeReadBuf->readNextRow(orientation, currentRRN);
-
- if (unlikely(!row))
- {
- rc = activeReadBuf->lastrc();
- if (rc == QMY_ERR_LOB_SPACE_TOO_SMALL)
- {
- rc = handleLOBReadOverflow();
- if (rc == 0)
- {
- DBUG_ASSERT(activeReadBuf->rowCount() == 1);
- row = activeReadBuf->readNextRow(orientation, currentRRN);
-
- if (unlikely(!row))
- rc = activeReadBuf->lastrc();
- }
- }
- }
-
- if (likely(rc == 0))
- {
- rrnAssocHandle = activeHandle;
- rc = mungeDB2row(destination, row, row+activeReadBuf->getRowNullOffset(), false);
- }
- return rc;
- }
-
- int32 handleLOBReadOverflow();
-
- char* getCharacterConversionBuffer(int fieldId, int length)
- {
- if (unlikely(!alloc_root_inited(&conversionBufferMemroot)))
- init_alloc_root(&conversionBufferMemroot, 8192, 0);
-
- return (char*)alloc_root(&conversionBufferMemroot, length);;
- }
-
- void resetCharacterConversionBuffers()
- {
- if (alloc_root_inited(&conversionBufferMemroot))
- {
- free_root(&conversionBufferMemroot, MYF(MY_MARK_BLOCKS_FREE));
- }
- }
-
- void tweakReadSet()
- {
- THD* thd = ha_thd();
- int command = thd_sql_command(thd);
- if ((command == SQLCOM_UPDATE ||
- command == SQLCOM_UPDATE_MULTI) ||
- ((command == SQLCOM_DELETE ||
- command == SQLCOM_DELETE_MULTI) &&
- thd->options & OPTION_BIN_LOG))
- readAllColumns = TRUE;
- else
- readAllColumns = FALSE;
- }
-
- /**
-
- */
- int useFileByHandle(char intent,
- FILE_HANDLE handle)
- {
- DBUG_ENTER("ha_ibmdb2i::useFileByHandle");
-
- const db2i_file* file;
- if (handle == dataHandle)
- file = db2Table->dataFile();
- else
- {
- for (uint i = 0; i < table_share->keys; ++i)
- {
- if (indexHandles[i] == handle)
- {
- file = db2Table->indexFile(i);
- active_index = i;
- }
- }
- }
-
- int rc = file->obtainRowFormat(handle, intent, getCommitLevel(), &activeFormat);
- if (likely(rc == 0))
- {
- activeHandle = handle;
- bumpInUseCounter(1);
- }
-
- DBUG_RETURN(rc);
- }
-
- const db2i_file* getFileForActiveHandle() const
- {
- if (activeHandle == dataHandle)
- return db2Table->dataFile();
- else
- for (uint i = 0; i < table_share->keys; ++i)
- if (indexHandles[i] == activeHandle)
- return db2Table->indexFile(i);
- DBUG_ASSERT(0);
- return NULL;
- }
-
- int prepReadBuffer(ha_rows rowsToRead, const db2i_file* file, char intent);
- int prepWriteBuffer(ha_rows rowsToWrite, const db2i_file* file);
-
- void invalidateCachedStats()
- {
- share->cachedStats.invalidate(rowCount | deletedRowCount | objLength |
- meanRowLen | ioCount);
- }
-
- void warnIfInvalidData()
- {
- if (unlikely(invalidDataFound))
- {
- warning(ha_thd(), DB2I_ERR_INVALID_DATA, table->alias);
- }
- }
-
- /**
- Calculate the maximum value that a particular field can hold.
-
- This is used to anticipate overflows in the auto_increment processing.
-
- @param field The Field to be analyzed
-
- @return The maximum value
- */
- static uint64 maxValueForField(const Field* field)
- {
- uint64 maxValue=0;
- switch (field->type())
- {
- case MYSQL_TYPE_TINY:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1 << 8) - 1;
- else
- maxValue = (1 << 7) - 1;
- break;
- case MYSQL_TYPE_SHORT:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1 << 16) - 1;
- else
- maxValue = (1 << 15) - 1;
- break;
- case MYSQL_TYPE_INT24:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1 << 24) - 1;
- else
- maxValue = (1 << 23) - 1;
- break;
- case MYSQL_TYPE_LONG:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1LL << 32) - 1;
- else
- maxValue = (1 << 31) - 1;
- break;
- case MYSQL_TYPE_LONGLONG:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = ~(0LL);
- else
- maxValue = 1 << 63 - 1;
- break;
- }
-
- return maxValue;
- }
-
- void cleanupBuffers()
- {
- if (blobReadBuffers)
- {
- delete blobReadBuffers;
- blobReadBuffers = NULL;
- }
- if (blobWriteBuffers)
- {
- delete[] blobWriteBuffers;
- blobWriteBuffers = NULL;
- }
- if (alloc_root_inited(&conversionBufferMemroot))
- {
- free_root(&conversionBufferMemroot, MYF(0));
- }
- }
-
-
-/**
- Generate a valid RCDFMT name based on the name of the table.
-
- The RCDFMT name is devised by munging the name of the table,
- uppercasing all ascii alpha-numeric characters and replacing all other
- characters with underscores until up to ten characters have been generated.
-
- @param tableName The name of the table, as given on the MySQL
- CREATE TABLE statement
- @param[out] query The string to receive the generated RCDFMT name
-*/
- static void generateAndAppendRCDFMT(const char* tableName, String& query)
- {
- char rcdfmt[11];
-
- // The RCDFMT name must begin with an alpha character.
- // We enforce this by skipping to the first alpha character in the table
- // name. If no alpha character exists, we use 'X' for the RCDFMT name;
-
- while (*tableName &&
- (!my_isascii(*tableName) ||
- !my_isalpha(system_charset_info, *tableName)))
- {
- tableName += my_mbcharlen(system_charset_info, *tableName);
- }
-
- if (unlikely(!(*tableName)))
- {
- rcdfmt[0]= 'X';
- rcdfmt[1]= 0;
- }
- else
- {
- int r= 0;
- while ((r < sizeof(rcdfmt)-1) && *tableName)
- {
- if (my_isascii(*tableName) &&
- my_isalnum(system_charset_info, *tableName))
- rcdfmt[r] = my_toupper(system_charset_info, *tableName);
- else
- rcdfmt[r] = '_';
-
- ++r;
- tableName += my_mbcharlen(system_charset_info, *tableName);
- }
- rcdfmt[r]= 0;
- }
- query.append(STRING_WITH_LEN(" RCDFMT "));
- query.append(rcdfmt);
- }
-
- int32 generateShadowIndex(SqlStatementStream& stream,
- const KEY& key,
- const char* libName,
- const char* fileName,
- const String& fieldDefinition);
-};
diff --git a/storage/ibmdb2i/plug.in b/storage/ibmdb2i/plug.in
deleted file mode 100644
index 0913d72aabf..00000000000
--- a/storage/ibmdb2i/plug.in
+++ /dev/null
@@ -1,12 +0,0 @@
-MYSQL_STORAGE_ENGINE([ibmdb2i], [], [IBM DB2 for i Storage Engine],
- [IBM DB2 for i Storage Engine], [max,max-no-ndb])
-MYSQL_PLUGIN_DYNAMIC([ibmdb2i], [ha_ibmdb2i.la])
-
-AC_CHECK_HEADER([qlgusr.h],
- # qlgusr.h is just one of the headers from the i5/OS PASE environment; the
- # EBCDIC headers are in /QIBM/include, and have to be converted to ASCII
- # before cpp gets to them
- [:],
- # Missing PASE environment, can't build this engine
- [mysql_plugin_ibmdb2i=no
- with_plugin_ibmdb2i=no])
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index 5317da78ee4..e185514b9c1 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -63,7 +63,7 @@ static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
{
- int subkeys, r;
+ int UNINIT_VAR(subkeys), r;
uint keylen, doc_cnt;
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 0b4d781379c..42bd8e26a94 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -38,7 +38,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
MI_CREATE_INFO *ci,uint flags)
{
register uint i,j;
- File UNINIT_VAR(dfile),file;
+ File UNINIT_VAR(dfile), UNINIT_VAR(file);
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
myf create_flag;
uint fields,length,max_key_length,packed,pointer,real_length_diff,
@@ -73,8 +73,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
}
- LINT_INIT(dfile);
- LINT_INIT(file);
errpos=0;
options=0;
bzero((uchar*) &share,sizeof(share));
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 18f8aa8d2c0..4bc3f7a4018 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -221,7 +221,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
int (*callback)(void*, const char*),
void *callback_param)
{
- MYRG_INFO *m_info;
+ MYRG_INFO *UNINIT_VAR(m_info);
int rc;
int errpos;
int save_errno;
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 3bfcf3ee233..ed8031b3fc3 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -1175,7 +1175,7 @@ my_bool fetch_n(const char **query_list, unsigned query_count,
/* Separate thread query to test some cases */
-static my_bool thread_query(char *query)
+static my_bool thread_query(const char *query)
{
MYSQL *l_mysql;
my_bool error;
@@ -1197,7 +1197,7 @@ static my_bool thread_query(char *query)
goto end;
}
l_mysql->reconnect= 1;
- if (mysql_query(l_mysql, (char *)query))
+ if (mysql_query(l_mysql, query))
{
fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql));
error= 1;
@@ -5821,7 +5821,7 @@ static void test_prepare_alter()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- if (thread_query((char *)"ALTER TABLE test_prep_alter change id id_new varchar(20)"))
+ if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
exit(1);
is_null= 1;