diff --git a/libgcobol/Makefile.am b/libgcobol/Makefile.am new file mode 100644 index 00000000000..31040320ec3 --- /dev/null +++ b/libgcobol/Makefile.am @@ -0,0 +1,152 @@ +# Copyright (C) 2025 Free Software Foundation, Inc. +# Contributed by the Symas Corporation, 2025 + +# This file is part of GCC. + +# GCC 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 3, or (at your option) +# any later version. + +# GCC 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 GCC; see the file COPYING3. If not see +# . + +# Written de novo for libgcobol. + +AUTOMAKE_OPTIONS = 1.8 foreign +ACLOCAL_AMFLAGS = -I .. -I ../config + +toolexeclib_LTLIBRARIES = libgcobol.la + +libgcobol.la: $(libgcobol_la_OBJECTS) \ + $(libgcobol_la_DEPENDENCIES) \ + $(EXTRA_libgcobol_la_DEPENDENCIES) + $(AM_V_GEN)$(libgcobol_la_LINK) \ + -rpath $(libdir)/../lib64 \ + $(libgcobol_la_OBJECTS) \ + $(libgcobol_la_LIBADD) $(LIBS) + + +## +## 2.2.12 Automatic Dependency Tracking +## Automake generates code for automatic dependency tracking by default +## +libgcobol_la_SOURCES = \ + charmaps.cc \ + constants.cc \ + gfileio.cc \ + gmath.cc \ + intrinsic.cc \ + io.cc \ + libgcobol.cc \ + valconv.cc + +# +# configure varables +# + +# Automatic +AM_CFLAGS = @CFLAGS@ +configure_input = @configure_input@ +AM_CPPFLAGS = @CPPFLAGS@ +AM_CXXFLAGS = @CXXFLAGS@ +DEFS = @DEFS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ERLCFLAGS = @ERLCFLAGS@ +FCFLAGS = @FCFLAGS@ +FFLAGS = @FFLAGS@ +AM_LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCXXFLAGS = @OBJCXXFLAGS@ +GOFLAGS = @GOFLAGS@ +builddir = @builddir@ +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +top_build_prefix = @top_build_prefix@ +abs_top_builddir = @abs_top_builddir@ +## srcdir see: overrides +abs_srcdir = @abs_srcdir@ +top_srcdir = @top_srcdir@ +abs_top_srcdir = @abs_top_srcdir@ + +# Installation +bindir = @bindir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ + +# Overrides and custom + +CC = @CC@ +CXX = @CXX@ +AR = @AR@ +AS = @AS@ +RANLIB = @RANLIB@ +LIBGCOBOL_VERSION = @LIBGCOBOL_VERSION@ +VERSION_SUFFIX = @VERSION_SUFFIX@ +LIBTOOL = @LIBTOOL@ $(LIBTOOLFLAGS) + +libgcobol_la_LFLAGS = -lstdc++ +libgcobol_la_LINK = $(LIBTOOL) --mode=link --tag=CXX $(CXX) \ + -o libgcobol$(libsuffix).la \ + -Wc,-shared-libgcc \ + -version-info $(LIBGCOBOL_VERSION) \ + -lstdc++ \ + $(LTLDFLAGS) + +# The 'all' rule must be the first one so that it is executed if +# nothing is specified on the command-line. +all: $(LIBGCOBOL_LA) + +.PHONY: install install-html install-pdf install-info + +###include $(top_srcdir)/../multilib.am +install: libgcobol$(libsuffix).la + $(LIBTOOL) --mode=install $(INSTALL) $^ $(DESTDIR)$(libdir)/../lib64 + +WARN_CFLAGS = -W -Wall -Wwrite-strings + +# not defined: DEFS, MAX_ERRORS, LTLDFLAGS +ALL_CFLAGS = -I. -I$(srcdir) $(AM_CPPFLAGS) $(DEFS) \ + $(XCFLAGS) $(AM_CXXFLAGS) $(WARN_CFLAGS) $(MAX_ERRORS) \ + -DIN_GCC -DIN_TARGET_LIBS -fno-strict-aliasing + +%.lo: %.c + $(LIBTOOL) --mode=compile $(CC) -c \ + -o $@ $(ALL_CFLAGS) $(INCLUDES) $< + +%.lo: %.cc + $(LIBTOOL) --mode=compile --tag=CXX $(CXX) -c \ + -o $@ $(INCLUDES) $(ALL_CFLAGS) $< + +doc: info dvi pdf html + +# No install-html or install-pdf support +install-html install-pdf install-info: + diff --git a/libgcobol/Makefile.in b/libgcobol/Makefile.in new file mode 100644 index 00000000000..78463b31e00 --- /dev/null +++ b/libgcobol/Makefile.in @@ -0,0 +1,976 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 2025 Free Software Foundation, Inc. +# Contributed by the Symas Corporation, 2025 + +# This file is part of GCC. + +# GCC 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 3, or (at your option) +# any later version. + +# GCC 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 GCC; see the file COPYING3. If not see +# . + +# Written de novo for libgcobol. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../config/toolexeclibdir.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ + $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/tls.m4 \ + $(top_srcdir)/../config/bitfields.m4 \ + $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(toolexeclibdir)" +LTLIBRARIES = $(toolexeclib_LTLIBRARIES) +libgcobol_la_LIBADD = +am_libgcobol_la_OBJECTS = charmaps.lo constants.lo gfileio.lo gmath.lo \ + intrinsic.lo io.lo libgcobol.lo valconv.lo +libgcobol_la_OBJECTS = $(am_libgcobol_la_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libgcobol_la_SOURCES) +DIST_SOURCES = $(libgcobol_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/../compile $(top_srcdir)/../config.guess \ + $(top_srcdir)/../config.sub $(top_srcdir)/../depcomp \ + $(top_srcdir)/../install-sh $(top_srcdir)/../ltmain.sh \ + $(top_srcdir)/../missing $(top_srcdir)/../mkinstalldirs \ + ChangeLog README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ + +# Overrides and custom +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGCOBOL_VERSION = @LIBGCOBOL_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ $(LIBTOOLFLAGS) +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPEC_LIBGCOBOL_DEPS = @SPEC_LIBGCOBOL_DEPS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +VERSION_SUFFIX = @VERSION_SUFFIX@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ + +# Installation +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_libsubdir = @build_libsubdir@ +build_os = @build_os@ +build_subdir = @build_subdir@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_shared = @enable_shared@ +enable_static = @enable_static@ +exec_prefix = @exec_prefix@ +extra_darwin_ldflags_libgcobol = @extra_darwin_ldflags_libgcobol@ +get_gcc_base_ver = @get_gcc_base_ver@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_noncanonical = @host_noncanonical@ +host_os = @host_os@ +host_subdir = @host_subdir@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +slibdir = @slibdir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_noncanonical = @target_noncanonical@ +target_os = @target_os@ +target_subdir = @target_subdir@ +target_vendor = @target_vendor@ +toolexecdir = @toolexecdir@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = 1.8 foreign +ACLOCAL_AMFLAGS = -I .. -I ../config +toolexeclib_LTLIBRARIES = libgcobol.la +libgcobol_la_SOURCES = \ + charmaps.cc \ + constants.cc \ + gfileio.cc \ + gmath.cc \ + intrinsic.cc \ + io.cc \ + libgcobol.cc \ + valconv.cc + + +# +# configure varables +# + +# Automatic +AM_CFLAGS = @CFLAGS@ +configure_input = @configure_input@ +AM_CPPFLAGS = @CPPFLAGS@ +AM_CXXFLAGS = @CXXFLAGS@ +ERLCFLAGS = @ERLCFLAGS@ +FCFLAGS = @FCFLAGS@ +FFLAGS = @FFLAGS@ +AM_LDFLAGS = @LDFLAGS@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCXXFLAGS = @OBJCXXFLAGS@ +GOFLAGS = @GOFLAGS@ +AS = @AS@ +libgcobol_la_LFLAGS = -lstdc++ +libgcobol_la_LINK = $(LIBTOOL) --mode=link --tag=CXX $(CXX) \ + -o libgcobol$(libsuffix).la \ + -Wc,-shared-libgcc \ + -version-info $(LIBGCOBOL_VERSION) \ + -lstdc++ \ + $(LTLDFLAGS) + +WARN_CFLAGS = -W -Wall -Wwrite-strings + +# not defined: DEFS, MAX_ERRORS, LTLDFLAGS +ALL_CFLAGS = -I. -I$(srcdir) $(AM_CPPFLAGS) $(DEFS) \ + $(XCFLAGS) $(AM_CXXFLAGS) $(WARN_CFLAGS) $(MAX_ERRORS) \ + -DIN_GCC -DIN_TARGET_LIBS -fno-strict-aliasing + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \ + } + +uninstall-toolexeclibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \ + done + +clean-toolexeclibLTLIBRARIES: + -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES) + @list='$(toolexeclib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/charmaps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constants.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gfileio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmath.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intrinsic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcobol.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/valconv.Plo@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) config.h +installdirs: + for dir in "$(DESTDIR)$(toolexeclibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-toolexeclibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-toolexeclibLTLIBRARIES + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ + clean-cscope clean-generic clean-libtool \ + clean-toolexeclibLTLIBRARIES cscope cscopelist-am ctags \ + ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \ + dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip install-toolexeclibLTLIBRARIES installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-toolexeclibLTLIBRARIES + +.PRECIOUS: Makefile + + +libgcobol.la: $(libgcobol_la_OBJECTS) \ + $(libgcobol_la_DEPENDENCIES) \ + $(EXTRA_libgcobol_la_DEPENDENCIES) + $(AM_V_GEN)$(libgcobol_la_LINK) \ + -rpath $(libdir)/../lib64 \ + $(libgcobol_la_OBJECTS) \ + $(libgcobol_la_LIBADD) $(LIBS) + +# The 'all' rule must be the first one so that it is executed if +# nothing is specified on the command-line. +all: $(LIBGCOBOL_LA) + +.PHONY: install install-html install-pdf install-info + +###include $(top_srcdir)/../multilib.am +install: libgcobol$(libsuffix).la + $(LIBTOOL) --mode=install $(INSTALL) $^ $(DESTDIR)$(libdir)/../lib64 + +%.lo: %.c + $(LIBTOOL) --mode=compile $(CC) -c \ + -o $@ $(ALL_CFLAGS) $(INCLUDES) $< + +%.lo: %.cc + $(LIBTOOL) --mode=compile --tag=CXX $(CXX) -c \ + -o $@ $(INCLUDES) $(ALL_CFLAGS) $< + +doc: info dvi pdf html + +# No install-html or install-pdf support +install-html install-pdf install-info: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libgcobol/README b/libgcobol/README new file mode 100644 index 00000000000..318c04e10d8 --- /dev/null +++ b/libgcobol/README @@ -0,0 +1,12 @@ +The libgcobol is intended for use entirely and solely by executables created +from COBOL source code by the GCOBOL "COBOL for GCC" front end. + +libgcobol.a can be staticly linked in, but it makes for very large binaries. We +tend to use that for debugging the GCOBOL compiler, and not much else + +Many of the functions in the library are called by the executable code generated +by the GCOBOL compiler through GIMPLE tags, and thus prototypes -- which are +part of the C/C++ programming paradigm -- are not used. Both the calling +program and the called program use the extern "C" construction so that the +linker can find the functions, and they need to agree ahead of time about the +meaning of passed parameters. diff --git a/libgcobol/acinclude.m4 b/libgcobol/acinclude.m4 new file mode 100644 index 00000000000..ed340c7977a --- /dev/null +++ b/libgcobol/acinclude.m4 @@ -0,0 +1,26 @@ +dnl Copyright (C) 2021-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +m4_include(../config/acx.m4) +m4_include(../config/no-executables.m4) +m4_include(../config/enable.m4) +m4_include(../config/tls.m4) +m4_include(../config/bitfields.m4) + +m4_include(../libtool.m4) +dnl The lines below arrange for aclocal not to bring an installed +dnl libtool.m4 into aclocal.m4, while still arranging for automake to +dnl add a definition of LIBTOOL to Makefile.in. +ifelse(yes,no,[ +AC_DEFUN([AM_PROG_LIBTOOL],) +AC_DEFUN([AC_LIBTOOL_DLOPEN],) +AC_DEFUN([AC_LIBLTDL_CONVENIENCE],) +AC_SUBST(LIBTOOL) +]) diff --git a/libgcobol/aclocal.m4 b/libgcobol/aclocal.m4 new file mode 100644 index 00000000000..1d5125ec2f0 --- /dev/null +++ b/libgcobol/aclocal.m4 @@ -0,0 +1,1199 @@ +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# Figure out how to run the assembler. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AS +# ---------- +AC_DEFUN([AM_PROG_AS], +[# By default we simply use the C compiler to build assembly code. +AC_REQUIRE([AC_PROG_CC]) +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS +AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)]) +AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)]) +_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([../config/depstand.m4]) +m4_include([../config/lead-dot.m4]) +m4_include([../config/multi.m4]) +m4_include([../config/override.m4]) +m4_include([../config/toolexeclibdir.m4]) +m4_include([../ltoptions.m4]) +m4_include([../ltsugar.m4]) +m4_include([../ltversion.m4]) +m4_include([../lt~obsolete.m4]) +m4_include([acinclude.m4]) diff --git a/libgcobol/charmaps.cc b/libgcobol/charmaps.cc new file mode 100644 index 00000000000..3b75c08dd2f --- /dev/null +++ b/libgcobol/charmaps.cc @@ -0,0 +1,929 @@ +// This file is included in both the libgcobol and gcc/cobol compilations +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "common-defs.h" +#include "io.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "charmaps.h" +#include "valconv.h" + +// First: single-byte-coded (SBC) character sets: + +// 7-bit ASCII is a subset of the various ISO/IEC 8859 code pages. +// 8859 is a subset of code page 1252. +// CP1252 is informally, and improperly, known as the "ANSI" code set. In +// modern usage, when somebody says "8859-1", they almost invariably are +// referring to a CP1252 code set. + +// EBCDIC is also an SBC character set. IBM's original "international EBCDIC" +// code set was Code Page 37, which did not have a Euro sign. Code Page 1140 +// is the same as CP37, but with the Euro sign replacing the "universal +// currency symbol" at position 0x9F. The table below maps the 256 values of +// CodePage 1140 to the 256 values of CodePage 1252 in a way that allows for +// "round trip" conversion without any loss. + +// See https://en.wikipedia.org/w/index.php?title=Code_page_37&oldid=1082467670, + +// The modern world increasingly uses UTF-8, which is in conflict with ordinary +// COBOL's inherently single-byte nature. In UTF-8, the encoding for a Euro +// sign is three bytes (U+20AC encodes to E2 A2 AC). In single-byte CP1252, the +// Euro is encoded as 0x80. + +// So, we are going to assume that internally, the generated COBOL executable +// operates in code page 1252 or [hopefully some day] code page 1140. + +// We will convert output, as in DISPLAY from the internal character +// set to the running machine's locale (for now, that locale will be assumed to +// be 1252/8859 if it isn't UTF-8). + +// And we will take some pains to figure out if the source code file was done +// as UTF-8; if not, we will assume 1252/8859-1 + +// __gg__ebcdic_codeset_in_use is the ultimate determinator of whether the +// internal codeset is ASCII/CP1252 or EBCDIC/CP1140. +bool __gg__ebcdic_codeset_in_use = false ; + +static text_codeset_t source_codeset = cs_cp1252_e; +static text_codeset_t console_codeset = cs_default_e; + +#define UNICODE_REPLACEMENT 0xFFFD // This a white question mark in a black diamond +#define ASCII_REPLACEMENT 0x87 // In CP1252, 0x87 is a double-dagger + +// This table is the default one-to-one mapping that's used, for example, when +// starting with ASCII and doing ASCII comparisons: + +const unsigned short +__gg__one_to_one_values[256] = + { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF + }; + +// This table can be used for converting EBCDIC values to CP1252. + +// There is an unfortunate caveat, one that undoubtedly will have unintended +// consequences. But COBOL has has the concept of a HIGH-VALUE, a character +// that theoretically tests alphanumercially greater than all other characters. +// In the CP1252 code page, the default HIGH-VALUE (it can be changed by the +// ALPHABET clause is 0xFF, which is displayed as the character 'ÿ'). In the +// EBCDIC code page 1140, that character is an EO control code. + +// So. In order that the default HIGH-VALUE once and always is 0xFF, these +// two tables have been modified slightly so that 0xFF always maps to 0xFF + +// Programmers who use the ALPHABET clause to change the HIGH-VALUE are on their +// own. + + +const unsigned short +__gg__cp1140_to_cp1252_values[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, + 0xA4, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0x80, + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, + 0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, 0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, /*0x9F*/ 0xFF, + }; + +// This table is the mirror image of cp1140_to_cp1252_values, except for the +// above-mentioned 0xFF +const unsigned short +__gg__cp1252_to_cp1140_values[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, + 0x9F, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, + 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, + 0x41, 0xAA, 0x4A, 0xB1, 0x20, 0xB2, 0x6A, 0xB5, 0xBD, 0xB4, 0x9A, 0x8A, 0x5F, 0xCA, 0xAF, 0xBC, + 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, + 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xAD, 0xAE, 0x59, + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, + 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, /*0xDF*/ 0xFF, + }; + +// This is the EBCDIC collating sequence when the internal character set is CP1252. It's actually +// a copy of __gg__cp1252_to_cp1140_values, but modified so that 0xFF maps to 0xFF. +// Doing this meant swapping the CP1252 upper-Y-umlaut with lower-Y-umlaut. +const unsigned short +__gg__cp1252_to_ebcdic_collation[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, + 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, + 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xba, 0xe0, 0xbb, 0xb0, 0x6d, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, + 0x9f, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b, + 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08, 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xdf, + 0x41, 0xaa, 0x4a, 0xb1, 0x20, 0xb2, 0x6a, 0xb5, 0xbd, 0xb4, 0x9a, 0x8a, 0x5f, 0xca, 0xaf, 0xbc, + 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, + 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xad, 0xae, 0x59, + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, + 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xff, + }; + +// When using the EBCDIC internal character set, but if told to use the ASCII collating sequence, +// this table can be used. It's based on the __gg__cp1140_to_cp1252_values, but with the two +// characters at locations DF and FF swapped so that the HIGH-VALUE 0xFF maps to 0xFF. +const unsigned short +__gg__ebcdic_to_cp1252_collation[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, + 0xA4, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0x80, + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, + 0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, 0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xDF, + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0xFF, + }; + +// This table is used for converting code page 1252 to the subset of UTF-8 that +// that contains CP1252 + +static const unsigned short +cp1252_to_utf8_values[256] = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, // 00 + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, // 10 + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, // 20 + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, // 30 + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, // 40 + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, // 50 + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, // 60 + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, // 70 + 0x20ac, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x017d, 0x008f, // 80 + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x017e, 0x0178, // 90 + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, // A0 + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, // B0 + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, // C0 + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, // D0 + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, // E0 + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, // F0 + }; + +// This map table doe the reverse UTF-8 conversion back to cp1252 +static const std::unordered_maputf8_to_cp1252_values = + { + {0x0000, 0x00}, {0x0001, 0x01}, {0x0002, 0x02}, {0x0003, 0x03}, {0x0004, 0x04}, {0x0005, 0x05}, {0x0006, 0x06}, {0x0007, 0x07}, + {0x0008, 0x08}, {0x0009, 0x09}, {0x000a, 0x0a}, {0x000b, 0x0b}, {0x000c, 0x0c}, {0x000d, 0x0d}, {0x000e, 0x0e}, {0x000f, 0x0f}, + {0x0010, 0x10}, {0x0011, 0x11}, {0x0012, 0x12}, {0x0013, 0x13}, {0x0014, 0x14}, {0x0015, 0x15}, {0x0016, 0x16}, {0x0017, 0x17}, + {0x0018, 0x18}, {0x0019, 0x19}, {0x001a, 0x1a}, {0x001b, 0x1b}, {0x001c, 0x1c}, {0x001d, 0x1d}, {0x001e, 0x1e}, {0x001f, 0x1f}, + {0x0020, 0x20}, {0x0021, 0x21}, {0x0022, 0x22}, {0x0023, 0x23}, {0x0024, 0x24}, {0x0025, 0x25}, {0x0026, 0x26}, {0x0027, 0x27}, + {0x0028, 0x28}, {0x0029, 0x29}, {0x002a, 0x2a}, {0x002b, 0x2b}, {0x002c, 0x2c}, {0x002d, 0x2d}, {0x002e, 0x2e}, {0x002f, 0x2f}, + {0x0030, 0x30}, {0x0031, 0x31}, {0x0032, 0x32}, {0x0033, 0x33}, {0x0034, 0x34}, {0x0035, 0x35}, {0x0036, 0x36}, {0x0037, 0x37}, + {0x0038, 0x38}, {0x0039, 0x39}, {0x003a, 0x3a}, {0x003b, 0x3b}, {0x003c, 0x3c}, {0x003d, 0x3d}, {0x003e, 0x3e}, {0x003f, 0x3f}, + {0x0040, 0x40}, {0x0041, 0x41}, {0x0042, 0x42}, {0x0043, 0x43}, {0x0044, 0x44}, {0x0045, 0x45}, {0x0046, 0x46}, {0x0047, 0x47}, + {0x0048, 0x48}, {0x0049, 0x49}, {0x004a, 0x4a}, {0x004b, 0x4b}, {0x004c, 0x4c}, {0x004d, 0x4d}, {0x004e, 0x4e}, {0x004f, 0x4f}, + {0x0050, 0x50}, {0x0051, 0x51}, {0x0052, 0x52}, {0x0053, 0x53}, {0x0054, 0x54}, {0x0055, 0x55}, {0x0056, 0x56}, {0x0057, 0x57}, + {0x0058, 0x58}, {0x0059, 0x59}, {0x005a, 0x5a}, {0x005b, 0x5b}, {0x005c, 0x5c}, {0x005d, 0x5d}, {0x005e, 0x5e}, {0x005f, 0x5f}, + {0x0060, 0x60}, {0x0061, 0x61}, {0x0062, 0x62}, {0x0063, 0x63}, {0x0064, 0x64}, {0x0065, 0x65}, {0x0066, 0x66}, {0x0067, 0x67}, + {0x0068, 0x68}, {0x0069, 0x69}, {0x006a, 0x6a}, {0x006b, 0x6b}, {0x006c, 0x6c}, {0x006d, 0x6d}, {0x006e, 0x6e}, {0x006f, 0x6f}, + {0x0070, 0x70}, {0x0071, 0x71}, {0x0072, 0x72}, {0x0073, 0x73}, {0x0074, 0x74}, {0x0075, 0x75}, {0x0076, 0x76}, {0x0077, 0x77}, + {0x0078, 0x78}, {0x0079, 0x79}, {0x007a, 0x7a}, {0x007b, 0x7b}, {0x007c, 0x7c}, {0x007d, 0x7d}, {0x007e, 0x7e}, {0x007f, 0x7f}, + {0x20ac, 0x80}, {0x0081, 0x81}, {0x201a, 0x82}, {0x0192, 0x83}, {0x201e, 0x84}, {0x2026, 0x85}, {0x2020, 0x86}, {0x2021, 0x87}, + {0x02c6, 0x88}, {0x2030, 0x89}, {0x0160, 0x8a}, {0x2039, 0x8b}, {0x0152, 0x8c}, {0x008d, 0x8d}, {0x017d, 0x8e}, {0x008f, 0x8f}, + {0x0090, 0x90}, {0x2018, 0x91}, {0x2019, 0x92}, {0x201c, 0x93}, {0x201d, 0x94}, {0x2022, 0x95}, {0x2013, 0x96}, {0x2014, 0x97}, + {0x02dc, 0x98}, {0x2122, 0x99}, {0x0161, 0x9a}, {0x203a, 0x9b}, {0x0153, 0x9c}, {0x009d, 0x9d}, {0x017e, 0x9e}, {0x0178, 0x9f}, + {0x00a0, 0xa0}, {0x00a1, 0xa1}, {0x00a2, 0xa2}, {0x00a3, 0xa3}, {0x00a4, 0xa4}, {0x00a5, 0xa5}, {0x00a6, 0xa6}, {0x00a7, 0xa7}, + {0x00a8, 0xa8}, {0x00a9, 0xa9}, {0x00aa, 0xaa}, {0x00ab, 0xab}, {0x00ac, 0xac}, {0x00ad, 0xad}, {0x00ae, 0xae}, {0x00af, 0xaf}, + {0x00b0, 0xb0}, {0x00b1, 0xb1}, {0x00b2, 0xb2}, {0x00b3, 0xb3}, {0x00b4, 0xb4}, {0x00b5, 0xb5}, {0x00b6, 0xb6}, {0x00b7, 0xb7}, + {0x00b8, 0xb8}, {0x00b9, 0xb9}, {0x00ba, 0xba}, {0x00bb, 0xbb}, {0x00bc, 0xbc}, {0x00bd, 0xbd}, {0x00be, 0xbe}, {0x00bf, 0xbf}, + {0x00c0, 0xc0}, {0x00c1, 0xc1}, {0x00c2, 0xc2}, {0x00c3, 0xc3}, {0x00c4, 0xc4}, {0x00c5, 0xc5}, {0x00c6, 0xc6}, {0x00c7, 0xc7}, + {0x00c8, 0xc8}, {0x00c9, 0xc9}, {0x00ca, 0xca}, {0x00cb, 0xcb}, {0x00cc, 0xcc}, {0x00cd, 0xcd}, {0x00ce, 0xce}, {0x00cf, 0xcf}, + {0x00d0, 0xd0}, {0x00d1, 0xd1}, {0x00d2, 0xd2}, {0x00d3, 0xd3}, {0x00d4, 0xd4}, {0x00d5, 0xd5}, {0x00d6, 0xd6}, {0x00d7, 0xd7}, + {0x00d8, 0xd8}, {0x00d9, 0xd9}, {0x00da, 0xda}, {0x00db, 0xdb}, {0x00dc, 0xdc}, {0x00dd, 0xdd}, {0x00de, 0xde}, {0x00df, 0xdf}, + {0x00e0, 0xe0}, {0x00e1, 0xe1}, {0x00e2, 0xe2}, {0x00e3, 0xe3}, {0x00e4, 0xe4}, {0x00e5, 0xe5}, {0x00e6, 0xe6}, {0x00e7, 0xe7}, + {0x00e8, 0xe8}, {0x00e9, 0xe9}, {0x00ea, 0xea}, {0x00eb, 0xeb}, {0x00ec, 0xec}, {0x00ed, 0xed}, {0x00ee, 0xee}, {0x00ef, 0xef}, + {0x00f0, 0xf0}, {0x00f1, 0xf1}, {0x00f2, 0xf2}, {0x00f3, 0xf3}, {0x00f4, 0xf4}, {0x00f5, 0xf5}, {0x00f6, 0xf6}, {0x00f7, 0xf7}, + {0x00f8, 0xf8}, {0x00f9, 0xf9}, {0x00fa, 0xfa}, {0x00fb, 0xfb}, {0x00fc, 0xfc}, {0x00fd, 0xfd}, {0x00fe, 0xfe}, {0x00ff, 0xff}, + }; + +// This function extracts the next unicode code point from a stream of UTF-8 +// data. + +static bool +raw_is_SBC() + { + bool retval = false; + switch(source_codeset) + { + case cs_cp1252_e: + retval = true; + break; + default: + break; + } + return retval; + } + + +static size_t +extract_next_code_point(const unsigned char *utf8, + const size_t /*length_in_bytes*/, + size_t &position) + { + long retval = -1; // Means a badly formed code point + unsigned char ch = utf8[position++]; + long under_construction = 0; + int countdown = 0; + + if( (ch & 0x80) == 0x00 ) + { + // We are in the ASCII subset of UTF-8, and we are done + retval = ch; + goto done; + } + else if( (ch & 0xE0) == 0xC0 ) + { + // There is one byte to follow + countdown = 1; + under_construction = ch & 0x1F; + } + else if( (ch & 0xF0) == 0xE0 ) + { + countdown = 2; + under_construction = ch & 0x0F; + } + else if( (ch & 0xF8) == 0xF0 ) + { + countdown = 3; + under_construction = ch & 0x07; + } + else + { + // We have a poorly-constructed UTF-8 encoding + goto done; + } + while( countdown-- ) + { + ch = utf8[position++]; + // We are in a follow-up encoded byte: + if( (ch & 0xC0) == 0x80 ) + { + // The top two bits are 10, so build in the bottom six bits + under_construction <<= 6; + under_construction |= (ch & 0x3F); + } + else + { + // This is a poorly-formed encoding + goto done; + } + } + retval = under_construction; + + done: + return retval; + } + +void flipper(void) + { + for(int i=0; i<256; i++) + { + fprintf(stderr, "{0x%4.4x, 0x%2.2x}, ", cp1252_to_utf8_values[i], i); + if( (i % 8) == 7 ) + { + fprintf(stderr, "\n"); + } + } + } + +extern "C" +char __gg__ascii_to_ascii_chr(char ch) + { + return ch; + } + +extern "C" +char __gg__ascii_to_ebcdic_chr(char ch) + { + return (char)__gg__cp1252_to_cp1140_values[(ch&0xFF)]; + } + +extern "C" +char * +__gg__raw_to_ascii(char **dest, size_t *dest_size, const char *in, size_t length) + { + // We are anticipating `length` characters, some of which might be multi- + // character UTF-8 codepoints. We are sending back a nul-terminated string + // of SBC ASCII values. + + __gg__realloc_if_necessary(dest, dest_size, length+1); + + // This is the byte position of the output + size_t index = 0; + + // This is the byte position of the input + size_t position = 0; + + while( index < length ) + { + // In the case of "display "âêîôû", when the source code is encoded in + // UTF-8, the field->data.capacity is showing up as 10, because that + // UTF-8 string is ten bytes long, and the parser is not counting + // characters. The data.initial field is indeed nul-terminated, so when we + // hit a nul, we bug out: + if( in[position] == '\0' ) + { + // We have hit the end. We want to space-fill to the right: + while( index < length ) + { + (*dest)[index++] = internal_space; + } + break; + } + + // Special handling for PIC X VALUE HIGH-VALUE. If we just hand default + // 0xFF values to the rest of the routine, the utf-8 detection will give + // us a result that confuses the remainder of the processing. + if( (in[position]&0xFF) == 0xFF ) + { + (*dest)[index++] = in[position++]; + continue; + } + + if( raw_is_SBC() ) + { + (*dest)[index++] = in[position++]; + continue; + } + + size_t code_point; + // Pull the next code_point from the UTF-8 stream + long unicode_point = extract_next_code_point((const unsigned char *)in, + length, + position ); + + // Check for that unicode code point in the subset of characters we + // know about: + std::unordered_map::const_iterator it = + utf8_to_cp1252_values.find(unicode_point); + if( it == utf8_to_cp1252_values.end() ) + { + // That unicode character isn't in our list + code_point = ASCII_REPLACEMENT; + } + else + { + code_point = it->second; + } + (*dest)[index++] = (char)code_point; + } + (*dest)[index++] = '\0'; + + return *dest; + } + +extern "C" +char * +__gg__raw_to_ebcdic(char **dest, size_t *dest_size, const char *in, size_t length) + { + // A UTF-8 string is at least as long as the single-byte-coded resulting + // string: + __gg__realloc_if_necessary(dest, dest_size, length+1); + + size_t index = 0; + + size_t position = 0; + size_t code_point; + while( index < length ) + { + // See comments in __gg__raw_to_ascii + if( in[position] == '\0' ) + { + // We have hit the end. We want to space-fill to the right: + while( index < length ) + { + (*dest)[index++] = internal_space; + } + break; + } + if( raw_is_SBC() ) + { + code_point = in[position++]; + long ebcdic_code_point = __gg__cp1252_to_cp1140_values[code_point&0xFF]; + (*dest)[index++] = ebcdic_code_point; + continue; + } + if( (in[position]&0xff) == 0xff ) + { + // HIGH-VALUE is a special case + (*dest)[index++] = in[position++]; + continue; + } + + // Pull the next code_point from the UTF-8 stream + long unicode_point = extract_next_code_point( (const unsigned char *)in, + length, + position ); + // Check for that unicode code point in the subset of characters we + // know about: + std::unordered_map::const_iterator it = + utf8_to_cp1252_values.find(unicode_point); + if( it == utf8_to_cp1252_values.end() ) + { + // That unicode character isn't in our list + code_point = ASCII_REPLACEMENT; + } + else + { + code_point = it->second; + } + // TODO: This could be sped up by creating a utf8_to_cp1140_values map. + // But sufficient unto the day are the evils thereof + long ebcdic_code_point = __gg__cp1252_to_cp1140_values[code_point&0xFF]; + (*dest)[index++] = ebcdic_code_point; + } + (*dest)[index++] = '\0'; + + return *dest; + } + +static +char * +convert_cp1252_to_utf8(char **dest, size_t *dest_size, const char *in, size_t length) + { + // Worst case is all unicode characters. + __gg__realloc_if_necessary(dest, dest_size, 4 * length + 1); + + size_t index = 0; + for(size_t i=0; i>6); + (*dest)[index++] = 0x80 + ((unicode_point>>0) & 0x3F); + } + else if(unicode_point < 0x10000) + { + // Three-byte: + (*dest)[index++] = 0xE0 + (unicode_point>>12); + (*dest)[index++] = 0x80 + ((unicode_point>>6) & 0x3F); + (*dest)[index++] = 0x80 + ((unicode_point>>0) & 0x3F); + } + else + { + // Four-byte: + (*dest)[index++] = 0xF0 + (unicode_point>>18); + (*dest)[index++] = 0x80 + ((unicode_point>>12) & 0x3F); + (*dest)[index++] = 0x80 + ((unicode_point>>6) & 0x3F); + (*dest)[index++] = 0x80 + ((unicode_point>>0) & 0x3F); + } + } + (*dest)[index++] = '\0'; + + return *dest; + } + +// This is the address of the 256-character map for internal characters +// It'll be set to one-to-one for ASCII, and to cp1252-to-cp1140_values for +// EBCDIC. +unsigned short const *__gg__internal_codeset_map; + +// Here is the list of function pointers establish which ones of the paired +// possibilities of conversion routines are actually in use. + +char (*__gg__ascii_to_internal_chr)(char); +void (*__gg__ascii_to_internal_str)(char *str, size_t length); +char *(*__gg__raw_to_internal)(char **dest, size_t *dest_size, const char *in, const size_t length); +char *(*__gg__internal_to_console_cm)(char **dest, size_t *dest_size, const char *in, size_t length); +void (*__gg__console_to_internal_cm)(char * const str, size_t length); +void (*__gg__internal_to_ascii)(char *str, size_t length); + +extern "C" +void __gg__set_internal_codeset(int use_ebcdic) + { + __gg__ebcdic_codeset_in_use = !!use_ebcdic; + } + +extern "C" +void __gg__text_conversion_override(text_device_t device, + text_codeset_t codeset) + { + // Establish the default sourcecode and console codesets, and + // establish the codeset conversion routines: + + if( internal_is_ebcdic ) + { +// fprintf(stderr, "Setting up EBCDIC\n"); + __gg__internal_codeset_map = __gg__cp1252_to_cp1140_values; + __gg__ascii_to_internal_chr = &__gg__ascii_to_ebcdic_chr; + __gg__ascii_to_internal_str = &__gg__ascii_to_ebcdic; + __gg__raw_to_internal = &__gg__raw_to_ebcdic; + __gg__internal_to_console_cm = &__gg__ebcdic_to_console; + __gg__console_to_internal_cm = &__gg__console_to_ebcdic; + __gg__internal_to_ascii = &__gg__ebcdic_to_ascii; + } + else + { +// fprintf(stderr, "Setting up ASCII\n"); + __gg__internal_codeset_map = __gg__one_to_one_values; + __gg__ascii_to_internal_chr = &__gg__ascii_to_ascii_chr; + __gg__ascii_to_internal_str = &__gg__ascii_to_ascii; + __gg__raw_to_internal = &__gg__raw_to_ascii; + __gg__internal_to_console_cm = &__gg__ascii_to_console; + __gg__console_to_internal_cm = &__gg__console_to_ascii; + __gg__internal_to_ascii = &__gg__ascii_to_ascii; + } + + switch(device) + { + case td_default_e: + { + // We are setting our codesets to the defaults + + // First, sort out the console: + + // It is my understanding that the environment variable LANG is + // supposed to be set by the terminal to indicate the terminal's + // current character set. Let's use that as the winner, even if + // that's not quite the way locale(3) works. + const char *envLANG = getenv("LANG"); + if( !envLANG ) + { + // This is odd. No "LANG"? + envLANG = setlocale(LC_CTYPE, NULL); + } + if( !envLANG ) + { + // This is even more odd. Pick something as a backup to the backup + envLANG = "UTF-8"; + } + if( envLANG ) + { + if( strcasestr(envLANG, "UTF-8") ) + { + console_codeset = cs_utf8_e; + } + else + { + // If it isn't UTF-8, then figure on it being CP1252 as a + // convenient way of specifying an SBC codeset. + console_codeset = cs_cp1252_e; + } + } + break; + } + + case td_sourcecode_e: + // Explicitly set the source code codeset: + source_codeset = codeset; + break; + + case td_console_e: + // Explicitly set the console codeset: + console_codeset = codeset; + break; + } + } + +extern "C" +void +__gg__ascii_to_ascii(char *, size_t ) + { + return; + } + +extern "C" +void +__gg__ascii_to_ebcdic(char *str, size_t length) + { + for(size_t i=0; i::const_iterator it + = utf8_to_cp1252_values.find(unicode_point); + if( it == utf8_to_cp1252_values.end() ) + { + // That unicode character isn't in our list + code_point = ASCII_REPLACEMENT; + } + else + { + code_point = it->second; + } + } + *dest++ = (char)code_point; + } + *dest++ = '\0'; + } + +extern "C" +void +__gg__console_to_ebcdic(char * const str, size_t length) + { + char *dest = str; + + size_t position = 0; + while( position < length ) + { + size_t code_point; + // Pull the next code_point from the UTF-8 stream + long unicode_point + = extract_next_code_point( (const unsigned char *)str, + length, + position ); + if( unicode_point == -1 ) + { + // The UTF-8 stream was poorly formed. + code_point = ASCII_REPLACEMENT; + } + else + { + // Check for that unicode code point in the subset of characters we + // know about: + std::unordered_map::const_iterator it + = utf8_to_cp1252_values.find(unicode_point); + if( it == utf8_to_cp1252_values.end() ) + { + // That unicode character isn't in our list + code_point = ASCII_REPLACEMENT; + } + else + { + code_point = it->second; + } + } + *dest++ = __gg__cp1252_to_cp1140_values[code_point&0xFF] ; + } + *dest++ = '\0'; + } + +extern "C" +size_t +_to_ctype(char * const location, size_t length) + { + // Converts from our internal codeset to the system LC_TYPE codeset + const char *fromcode; + const char *tocode; + if( __gg__ebcdic_codeset_in_use ) + { + fromcode = "CP1140"; + } + else + { + fromcode = "CP1252"; + } + const char *ctype = setlocale(LC_CTYPE, ""); + + if( strcasestr(ctype, "UTF") ) + { + tocode = "UTF-8"; + } + else + { + tocode = "CP1252"; + } + + iconv_t cd = iconv_open(tocode, fromcode); + assert( cd != (iconv_t)-1 ); + + static char *dest = NULL; + static size_t dest_size = 0; + + // create a buffer long enough that iconv() won't fail: + __gg__realloc_if_necessary(&dest, &dest_size, 4*length+1); + + // Set up for the iconv() call: + char *inbuf = location; + size_t inbytesleft = length; + char *outbuf = dest; + size_t outbytesleft = 2*length+1; + + memset(dest, ' ', 2*length+1); + iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + memcpy(location, dest, length); + return 0; + } + +extern "C" +size_t +_from_ctype(char * const location, size_t length) + { + // Converts from our internal codeset to the system LC_TYPE codeset + const char *fromcode; + const char *tocode; + if( __gg__ebcdic_codeset_in_use ) + { + tocode = "CP1140"; + } + else + { + tocode = "CP1252"; + } + const char *ctype = setlocale(LC_CTYPE, ""); + + if( strcasestr(ctype, "UTF") ) + { + fromcode = "UTF-8"; + } + else + { + fromcode = "CP1252"; + } + + iconv_t cd = iconv_open(tocode, fromcode); + assert( cd != (iconv_t)-1 ); + + static char *dest = NULL; + static size_t dest_size = 0; + + // create a buffer long enough that iconv() won't fail: + __gg__realloc_if_necessary(&dest, &dest_size, length+1); + + // Set up for the iconv() call: + char *inbuf = location; + size_t inbytesleft = length; + char *outbuf = dest; + size_t outbytesleft = length+1; + + memset(dest, internal_space, length+1); + ///size_t iret = + iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + memcpy(location, dest, length); + return 0; + } diff --git a/libgcobol/charmaps.h b/libgcobol/charmaps.h new file mode 100644 index 00000000000..12968fdf928 --- /dev/null +++ b/libgcobol/charmaps.h @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CHARMAPS_H +#define CHARMAPS_H + +#include + +/* There are four distinct codeset domains in the COBOL compiler. + * + * First is the codeset of the console. Established by looking at what + * setlocale() reports, this can be either UTF-8 or some ASCII based code + * page. (We assume CP1252). Data coming from the console or the system, + * ACCEPT statements; redirected console input, getenv() and other system + * calls are in the "console" domain. + * + * Second is the internal single-byte-coded codeset of the data, in memory, + * being manipulated by the generated code of the cobol executable. The actual + * codeset of "internal" is either EBCDIC (in the form of Code Page 1140 or + * ASCII (Code Page 1252) + * + * Third is the C++ source code of the GCOBOL compiler; this comment is + * in that environment. We neither know, nor care, if this code is encoded in + * in UTF-8 (as is probable, in these enlighted days of 2022) or something like + * Code Page1252. We are going to regard it as "ascii" under the + * assumption that there is no reason for any character in the compiler's + * source code to have a code point outside of the plain vanilla 0x20 through + * 0x7F range. + * + * Fourth is the "raw" COBOL source code that is the input to the GCOBOL + * compiler. This domain can be either UTF-8 or something like CodePage1252. + * Which encoding is relevant; The literal string MOVE "1234" is seven + * bytes long in UTF-8, and five bytes long in CP1252. We start with an + * assumption that it is UTF-8 and switch to CP1252 upon encountering a byte + * sequence with values above 0x80 that can't be UTF-8. We have provision for + * forcing it to be one or the other. Codepoints in that domain are referenced + * as "raw". Codepoint in the "raw" domain don't last long; they are be + * converted to either "ascii" or "internal" early on, as necessary. + */ + + +/* Notes on character codesets: + + This library is implemented to handle "native" codesets of either ASCII (in + the form of a single-byte-coded codeset like code page 1252) or EBCDIC (in + the form of a single-byte-coded codeset like code page 1140). + + This C/C++ source code, however, is assumed to be an ASCII-based codeset, + so that a character constant like a space is assumed to encode as 0x20. + + Furthermore, we assume that the codeset of the COBOL source code being + compiled is also ASCII-based, even if it is actually UTF-8. Said another + way, characters encoded between zero and 127 are regarded as ASCII. + + This means that we are not going to try to compile EBCDIC COBOL source code; + any such will have to be externally converted to ASCII before feeding it + through this compiler on an ASCII based Linux system. + + This situation is rife for confusion here in the source code for the + library. + + To help reduce that confusion, we are going to eschew character constants + in the C/C++ source code. Instead, we use symbolic versions. In general, + "source_space" means 0x20, while "internal_space" will be either 0x20 + when using the ASCII-based native codeset, or it will be 0x40 when using + the EBCDIC-based native codeset. + + Maintaining one's sanity while learning and working with this C/C++ code + will require a firm grip on context. You'll have to keep track of whether + the character is being used to analyze the ASCII-based COBOL source, or + whether the character in question is part of the native COBOL cobol data + that is being analyzed or generated. + + For example, when a PICTURE string has in it a source_nine, the generated + result in the variable is based on character_zero. + + Stay alert! */ + + +extern bool __gg__ebcdic_codeset_in_use; +#define internal_is_ebcdic (__gg__ebcdic_codeset_in_use) + +extern unsigned short const *__gg__internal_codeset_map; + +#define NULLCH ('\0') +#define DEGENERATE_HIGH_VALUE 0xFF +#define DEGENERATE_LOW_VALUE 0x00 + +#define ascii_A ((uint8_t)('A')) +#define ascii_B ((uint8_t)('B')) +#define ascii_C ((uint8_t)('C')) +#define ascii_D ((uint8_t)('D')) +#define ascii_E ((uint8_t)('E')) +#define ascii_F ((uint8_t)('F')) +#define ascii_G ((uint8_t)('G')) +#define ascii_H ((uint8_t)('H')) +#define ascii_I ((uint8_t)('I')) +#define ascii_J ((uint8_t)('J')) +#define ascii_K ((uint8_t)('K')) +#define ascii_L ((uint8_t)('L')) +#define ascii_M ((uint8_t)('M')) +#define ascii_N ((uint8_t)('N')) +#define ascii_O ((uint8_t)('O')) +#define ascii_P ((uint8_t)('P')) +#define ascii_Q ((uint8_t)('Q')) +#define ascii_R ((uint8_t)('R')) +#define ascii_S ((uint8_t)('S')) +#define ascii_T ((uint8_t)('T')) +#define ascii_U ((uint8_t)('U')) +#define ascii_V ((uint8_t)('V')) +#define ascii_W ((uint8_t)('W')) +#define ascii_X ((uint8_t)('X')) +#define ascii_Y ((uint8_t)('Y')) +#define ascii_Z ((uint8_t)('Z')) +#define ascii_a ((uint8_t)('a')) +#define ascii_b ((uint8_t)('b')) +#define ascii_c ((uint8_t)('c')) +#define ascii_d ((uint8_t)('d')) +#define ascii_e ((uint8_t)('e')) +#define ascii_f ((uint8_t)('f')) +#define ascii_g ((uint8_t)('g')) +#define ascii_h ((uint8_t)('h')) +#define ascii_i ((uint8_t)('i')) +#define ascii_j ((uint8_t)('j')) +#define ascii_k ((uint8_t)('k')) +#define ascii_l ((uint8_t)('l')) +#define ascii_m ((uint8_t)('m')) +#define ascii_n ((uint8_t)('n')) +#define ascii_o ((uint8_t)('o')) +#define ascii_p ((uint8_t)('p')) +#define ascii_q ((uint8_t)('q')) +#define ascii_r ((uint8_t)('r')) +#define ascii_s ((uint8_t)('s')) +#define ascii_t ((uint8_t)('t')) +#define ascii_u ((uint8_t)('u')) +#define ascii_v ((uint8_t)('v')) +#define ascii_w ((uint8_t)('w')) +#define ascii_x ((uint8_t)('x')) +#define ascii_y ((uint8_t)('y')) +#define ascii_z ((uint8_t)('z')) +#define ascii_space ((uint8_t)(' ')) +#define ascii_zero ((uint8_t)('0')) +#define ascii_0 ((uint8_t)('0')) +#define ascii_1 ((uint8_t)('1')) +#define ascii_2 ((uint8_t)('2')) +#define ascii_3 ((uint8_t)('3')) +#define ascii_4 ((uint8_t)('4')) +#define ascii_5 ((uint8_t)('5')) +#define ascii_6 ((uint8_t)('6')) +#define ascii_7 ((uint8_t)('7')) +#define ascii_8 ((uint8_t)('8')) +#define ascii_9 ((uint8_t)('9')) +#define ascii_nine ((uint8_t)('9')) +#define ascii_period ((uint8_t)('.')) +#define ascii_colon ((uint8_t)(':')) +#define ascii_comma ((uint8_t)(',')) +#define ascii_dollar_sign ((uint8_t)('$')) +#define ascii_dquote ((uint8_t)('"')) +#define ascii_oparen ((uint8_t)('(')) +#define ascii_caret ((uint8_t)('^')) +#define ascii_slash ((uint8_t)('/')) +#define ascii_plus ((uint8_t)('+')) +#define ascii_minus ((uint8_t)('-')) +#define ascii_hyphen ((uint8_t)('-')) +#define ascii_underscore ((uint8_t)('_')) +#define ascii_asterisk ((uint8_t)('*')) +#define ascii_query ((uint8_t)('?')) +#define ascii_cr ((uint8_t)('\r')) +#define ascii_ff ((uint8_t)('\f')) +#define ascii_newline ((uint8_t)('\n')) +#define ascii_return ((uint8_t)('\r')) + +#define internal_space ((uint8_t)__gg__internal_codeset_map[ascii_space]) +#define internal_zero ((uint8_t)__gg__internal_codeset_map[ascii_zero]) +#define internal_period ((uint8_t)__gg__internal_codeset_map[ascii_period]) +#define internal_comma ((uint8_t)__gg__internal_codeset_map[ascii_comma]) +#define internal_dquote ((uint8_t)__gg__internal_codeset_map[ascii_dquote]) +#define internal_asterisk ((uint8_t)__gg__internal_codeset_map[ascii_asterisk]) +#define internal_plus ((uint8_t)__gg__internal_codeset_map[ascii_plus]) +#define internal_minus ((uint8_t)__gg__internal_codeset_map[ascii_minus]) +#define internal_cr ((uint8_t)__gg__internal_codeset_map[ascii_cr]) +#define internal_ff ((uint8_t)__gg__internal_codeset_map[ascii_ff]) +#define internal_newline ((uint8_t)__gg__internal_codeset_map[ascii_newline]) +#define internal_return ((uint8_t)__gg__internal_codeset_map[ascii_return]) +#define internal_0 ((uint8_t)__gg__internal_codeset_map[ascii_0]) +#define internal_1 ((uint8_t)__gg__internal_codeset_map[ascii_1]) +#define internal_2 ((uint8_t)__gg__internal_codeset_map[ascii_2]) +#define internal_3 ((uint8_t)__gg__internal_codeset_map[ascii_3]) +#define internal_4 ((uint8_t)__gg__internal_codeset_map[ascii_4]) +#define internal_5 ((uint8_t)__gg__internal_codeset_map[ascii_5]) +#define internal_6 ((uint8_t)__gg__internal_codeset_map[ascii_6]) +#define internal_7 ((uint8_t)__gg__internal_codeset_map[ascii_7]) +#define internal_8 ((uint8_t)__gg__internal_codeset_map[ascii_8]) +#define internal_9 ((uint8_t)__gg__internal_codeset_map[ascii_9]) +#define internal_colon ((uint8_t)__gg__internal_codeset_map[ascii_colon]) +#define internal_query ((uint8_t)__gg__internal_codeset_map[ascii_query]) +#define internal_A ((uint8_t)__gg__internal_codeset_map[ascii_A]) +#define internal_B ((uint8_t)__gg__internal_codeset_map[ascii_B]) +#define internal_C ((uint8_t)__gg__internal_codeset_map[ascii_C]) +#define internal_D ((uint8_t)__gg__internal_codeset_map[ascii_D]) +#define internal_E ((uint8_t)__gg__internal_codeset_map[ascii_E]) +#define internal_F ((uint8_t)__gg__internal_codeset_map[ascii_F]) +#define internal_G ((uint8_t)__gg__internal_codeset_map[ascii_G]) +#define internal_H ((uint8_t)__gg__internal_codeset_map[ascii_H]) +#define internal_I ((uint8_t)__gg__internal_codeset_map[ascii_I]) +#define internal_J ((uint8_t)__gg__internal_codeset_map[ascii_J]) +#define internal_K ((uint8_t)__gg__internal_codeset_map[ascii_K]) +#define internal_L ((uint8_t)__gg__internal_codeset_map[ascii_L]) +#define internal_M ((uint8_t)__gg__internal_codeset_map[ascii_M]) +#define internal_N ((uint8_t)__gg__internal_codeset_map[ascii_N]) +#define internal_O ((uint8_t)__gg__internal_codeset_map[ascii_O]) +#define internal_P ((uint8_t)__gg__internal_codeset_map[ascii_P]) +#define internal_Q ((uint8_t)__gg__internal_codeset_map[ascii_Q]) +#define internal_R ((uint8_t)__gg__internal_codeset_map[ascii_R]) +#define internal_S ((uint8_t)__gg__internal_codeset_map[ascii_S]) +#define internal_T ((uint8_t)__gg__internal_codeset_map[ascii_T]) +#define internal_U ((uint8_t)__gg__internal_codeset_map[ascii_U]) +#define internal_V ((uint8_t)__gg__internal_codeset_map[ascii_V]) +#define internal_W ((uint8_t)__gg__internal_codeset_map[ascii_W]) +#define internal_X ((uint8_t)__gg__internal_codeset_map[ascii_X]) +#define internal_Y ((uint8_t)__gg__internal_codeset_map[ascii_Y]) +#define internal_Z ((uint8_t)__gg__internal_codeset_map[ascii_Z]) +#define internal_a ((uint8_t)__gg__internal_codeset_map[ascii_a]) +#define internal_b ((uint8_t)__gg__internal_codeset_map[ascii_b]) +#define internal_c ((uint8_t)__gg__internal_codeset_map[ascii_c]) +#define internal_d ((uint8_t)__gg__internal_codeset_map[ascii_d]) +#define internal_e ((uint8_t)__gg__internal_codeset_map[ascii_e]) +#define internal_f ((uint8_t)__gg__internal_codeset_map[ascii_f]) +#define internal_g ((uint8_t)__gg__internal_codeset_map[ascii_g]) +#define internal_h ((uint8_t)__gg__internal_codeset_map[ascii_h]) +#define internal_i ((uint8_t)__gg__internal_codeset_map[ascii_i]) +#define internal_j ((uint8_t)__gg__internal_codeset_map[ascii_j]) +#define internal_k ((uint8_t)__gg__internal_codeset_map[ascii_k]) +#define internal_l ((uint8_t)__gg__internal_codeset_map[ascii_l]) +#define internal_m ((uint8_t)__gg__internal_codeset_map[ascii_m]) +#define internal_n ((uint8_t)__gg__internal_codeset_map[ascii_n]) +#define internal_o ((uint8_t)__gg__internal_codeset_map[ascii_o]) +#define internal_p ((uint8_t)__gg__internal_codeset_map[ascii_p]) +#define internal_q ((uint8_t)__gg__internal_codeset_map[ascii_q]) +#define internal_r ((uint8_t)__gg__internal_codeset_map[ascii_r]) +#define internal_s ((uint8_t)__gg__internal_codeset_map[ascii_s]) +#define internal_t ((uint8_t)__gg__internal_codeset_map[ascii_t]) +#define internal_u ((uint8_t)__gg__internal_codeset_map[ascii_u]) +#define internal_v ((uint8_t)__gg__internal_codeset_map[ascii_v]) +#define internal_w ((uint8_t)__gg__internal_codeset_map[ascii_w]) +#define internal_x ((uint8_t)__gg__internal_codeset_map[ascii_x]) +#define internal_y ((uint8_t)__gg__internal_codeset_map[ascii_y]) +#define internal_z ((uint8_t)__gg__internal_codeset_map[ascii_z]) + + +enum text_device_t + { + td_default_e, + td_sourcecode_e, + td_console_e, + }; + +enum text_codeset_t + { + cs_default_e, + cs_utf8_e, + cs_cp1252_e, + cs_cp1140_e + }; + + +extern unsigned char __gg__data_space[1] ; +extern unsigned char __gg__data_low_values[1] ; +extern unsigned char __gg__data_zeros[1] ; +extern unsigned char __gg__data_high_values[1] ; +extern unsigned char __gg__data_quotes[1] ; +extern unsigned char __gg__data_upsi_0[2] ; +extern unsigned char __gg__data_return_code[2] ; + +// These are the various hardcoded tables used for conversions. +extern const unsigned short __gg__one_to_one_values[256]; +extern const unsigned short __gg__cp1252_to_cp1140_values[256]; +extern const unsigned short __gg__cp1140_to_cp1252_values[256]; + +// These are the two standard collations. +extern const unsigned short __gg__cp1252_to_ebcdic_collation[256]; +extern const unsigned short __gg__ebcdic_to_cp1252_collation[256]; + +// As described above, we have a number of operations we need to accomplish. But +// the actual routines are dependent on whether EBCDIC or ASCII is in use. We +// implement that by having a function pointer for each function; those pointers +// are established when the __gg__ebcdic_codeset_in_use variable is established. + +// These routines convert a single ASCII character to either ASCII or EBCDIC + +extern "C" +char __gg__ascii_to_ascii_chr(char ch); +extern "C" +char __gg__ascii_to_ebcdic_chr(char ch); +extern "C" +char (*__gg__ascii_to_internal_chr)(char); +#define ascii_to_internal(a) ((*__gg__ascii_to_internal_chr)(a)) + +extern "C" +void __gg__ascii_to_ascii(char *str, size_t length); +extern "C" +void __gg__ascii_to_ebcdic(char *str, size_t length); +extern "C" +void (*__gg__ascii_to_internal_str)(char *str, size_t length); +#define ascii_to_internal_str(a, b) ((*__gg__ascii_to_internal_str)((a), (b))) + +extern "C" +char *__gg__raw_to_ascii(char **dest, size_t *dest_size, const char *str, size_t length); +extern "C" +char *__gg__raw_to_ebcdic(char **dest, size_t *dest_size, const char *in, size_t length); +extern "C" +char *(*__gg__raw_to_internal)(char **dest, size_t *dest_length, const char *in, size_t length); +#define raw_to_internal(a, b, c, d) ((*__gg__raw_to_internal)((a), (b), (c), (d))) + +extern "C" +char *__gg__ascii_to_console(char **dest, size_t *dest_size, char const * const str, const size_t length); +extern "C" +char *__gg__ebcdic_to_console(char **dest, size_t *dest_size, char const * const str, const size_t length); +extern "C" +char *(*__gg__internal_to_console_cm)(char **dest, size_t *dest_size, const char *in, size_t length); +#define internal_to_console(a, b, c, d) ((*__gg__internal_to_console_cm)((a), (b), (c), (d))) + +extern "C" +void __gg__console_to_ascii(char * const str, size_t length); +extern "C" +void __gg__console_to_ebcdic(char * const str, size_t length); +extern "C" +void (*__gg__console_to_internal_cm)(char * const str, size_t length); +#define console_to_internal(a, b) ((*__gg__console_to_internal_cm)((a), (b))) + +extern "C" +void __gg__ebcdic_to_ascii(char *str, const size_t length); +extern "C" +void (*__gg__internal_to_ascii)(char *str, size_t length); +#define internal_to_ascii(a, b) ((*__gg__internal_to_ascii)((a), (b))) + +extern "C" void __gg__set_internal_codeset(int use_ebcdic); + +extern "C" +void __gg__text_conversion_override(text_device_t device, + text_codeset_t codeset); + +#endif \ No newline at end of file diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h new file mode 100644 index 00000000000..d052f58b6df --- /dev/null +++ b/libgcobol/common-defs.h @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef COMMON_DEFS_H_ +#define COMMON_DEFS_H_ + +#include +#include + +#define COUNT_OF(X) (sizeof(X) / sizeof(X[0])) + +// This constant establishes the maximum number of digits in a fixed point +// number. We are using 37 digits as a maximum because a full-size 37-digit +// number (10**37) takes 123 bits, and a full-size 38-digit number (10**38) +// takes 127 bits. By using a maximum of 37, that gives us an additional digit +// of headroom in order to accomplish rounding. + +// You should keep in mind that the _Float128 binary floating point numbers that +// we use can reliably reproduce numbers of 33 decimal digits when going to +// binary and back. + +#define MAX_FIXED_POINT_DIGITS (37) + +// COBOL tables can have up to seven subscripts +#define MAXIMUM_TABLE_DIMENSIONS 7 + +// This bit gets turned on in the first or last byte (depending on the leading_e attribute +// phrase) of a NumericDisplay to indicate that the value is negative. + +// When running the EBCDIC character set, the meaning of this bit is flipped, +// because an EBCDIC zero is 0xF0, while ASCII is 0x30 +#define NUMERIC_DISPLAY_SIGN_BIT 0x40 + +#define LEVEL01 (1) +#define LEVEL49 (49) +#define LEVEL77 (77) + +// In the __gg__move_literala() call, we piggyback this bit onto the +// cbl_round_t parameter, just to cut down on the number of parameters passed +#define REFER_ALL_BIT 0x80 + + +/* + * User-defined names in IBM COBOL can have at most 30 characters. + * For DBCS, the maximum is 14. + * + * Per ISO/IEC 1989:2023(E), 8.3.2 COBOL words, + * "A COBOL word is a character-string of not more than 63 characters" + */ +typedef char cbl_name_t[64]; + +// Note that the field_type enum is duplicated in the source code for the +// COBOL-aware GDB, and so any changes here (or there) have to be reflected +// there (or here) + +// Note further that if this list changes, then the valid_move() matrix has to +// change as will. Currently that matrix is in util.cc. + +enum cbl_field_type_t { + FldInvalid, // uninitialized + FldGroup, + FldAlphanumeric, // For X(n). + FldNumericBinary, // For 999v9 comp big-endian, 1 to 16 bytes + FldFloat, // 4-, 8-, and 16-byte floating point. See ieeedec_e and big_endian_e flags + FldPacked, // For 999v9 comp-3 internal decimal, packed decimal representation; + FldNumericBin5, // For 999v9 comp-5 little-endian, 1 to 16 bytes. (Native binary) + FldNumericDisplay, // For 999v9 one decimal character per byte + FldNumericEdited, // For 999.9 PIC BPVZ90/,.+-CRDB*cs; must have one of B/Z0,.*+-CRDBcs + FldAlphaEdited, // PIC AX9B0/; must have at least one A or X, and at least one B0/ + FldLiteralA, // Alphanumeric literal + FldLiteralN, // Numeric literal + FldClass, + FldConditional, // Target for parser_relop() + FldForward, + FldIndex, + FldSwitch, + FldDisplay, + FldPointer, + FldBlob, +}; + + +/* BINARY, COMP, COMPUTATIONAL, COMP-4, COMPUTATIONAL-4 are the same: + * Storage, by default, is big-endian. + * PIC 9(1 to 4) is 2 bytes + * PIC 9(5 to 9) is 4 bytes + * PIC 9(10 to 18) is 8 bytes + * PIC 9(19-37) is 16 bytes + * COMP-1, COMPUTATIONAL-1 + * 4-byte floating point (single) + * COMP-2, COMPUTATIONAL-2 + * 8-byte floating point (double) + * PACKED-DECIMAL, COMP-3, COMPUTATIONAL-3 + * Packed decimal. Final nybble is 0xF for unsigned numbers. For signable + * values, it is 0xD for negative, and 0xC for non-negative + * COMP-5, COMPUTATIONAL-5 + * Native binary. The maximum number of digits is implied by + * the 2, 4, or 8 bytes of data storage. By "native", little-endian + * is implied on Intel processors. + */ + +/* + * Enumerated bit mask of variable attributes. + * A field as either left- or right-justified. + * A field is padded (in the unjustified direction) either with 0 or SPC. + * (But maybe the fill character should just be an explicit character.) + */ +enum cbl_field_attr_t : size_t { + none_e = 0x0000000000, + figconst_1_e = 0x0000000001, // This needs to be 1 - don't change the position + figconst_2_e = 0x0000000002, // This needs to be 2 + figconst_4_e = 0x0000000004, // This needs to be 4 + rjust_e = 0x0000000008, // justify right + ljust_e = 0x0000000010, // justify left + zeros_e = 0x0000000020, // zero fill + signable_e = 0x0000000040, + constant_e = 0x0000000080, // pre-assigned constant + function_e = 0x0000000100, + quoted_e = 0x0000000200, + filler_e = 0x0000000400, + _spare_e = 0x0000000800, // + intermediate_e = 0x0000001000, // Compiler-defined temporary variable + embiggened_e = 0x0000002000, // redefined numeric made 64-bit by USAGE POINTER + all_alpha_e = 0x0000004000, // FldAlphanumeric, but all A's + all_x_e = 0x0000008000, // picture is all X's + all_ax_e = 0x000000a000, // picture is all A's or all X's + prog_ptr_e = 0x0000010000, // FUNCTION-POINTER or PROGRAM-POINTER + scaled_e = 0x0000020000, + refmod_e = 0x0000040000, // Runtime; indicates a refmod is active + based_e = 0x0000080000, // pointer capacity, for ADDRESS OF or ALLOCATE + any_length_e = 0x0000100000, // inferred length of linkage in nested program + global_e = 0x0000200000, // field has global scope + external_e = 0x0000400000, // field has external scope + blank_zero_e = 0x0000800000, // BLANK WHEN ZERO + // data division uses 2 low bits of high byte + linkage_e = 0x0001000000, // field is in linkage section + local_e = 0x0002000000, // field is in local section + leading_e = 0x0004000000, // leading sign (signable_e alone means trailing) + separate_e = 0x0008000000, // separate sign + envar_e = 0x0010000000, // names an environment variable + dnu_1_e = 0x0020000000, // unused: this attribute bit is available + bool_encoded_e = 0x0040000000, // data.initial is a boolean string + hex_encoded_e = 0x0080000000, // data.initial is a hex-encoded string + depends_on_e = 0x0100000000, // A group hierachy contains a DEPENDING_ON + initialized_e = 0x0200000000, // Don't call parser_initialize from parser_symbol_add + has_value_e = 0x0400000000, // Flag to hierarchical descendents to ignore .initial + ieeedec_e = 0x0800000000, // Indicates a FldFloat is IEEE 754 decimal, rather than binary + big_endian_e = 0x1000000000, // Indicates a value is big-endian + same_as_e = 0x2000000000, // Field produced by SAME AS (cannot take new members) + record_key_e = 0x4000000000, + typedef_e = 0x8000000000, // IS TYPEDEF + strongdef_e = typedef_e + intermediate_e, // STRONG TYPEDEF (not temporary) +}; +// The separate_e value does double-duty for FldPacked/COMP-6, which is not +// the same as FldPacked COMP-3. A COMP-3 can have signable_e, meaning that the +// final nybble is 0x0D for negative, and 0x0C for non-negative. When a COMP-3 +// has no sign, then the final nybble is 0x0F. The packed_no_sign_e bit means +// that there is no sign nybble. +#define packed_no_sign_e separate_e + +enum cbl_figconst_t + { + normal_value_e = 0, // This one must be zero + low_value_e = 1, // The order is important, because + null_value_e = 2, + zero_value_e = 3, // at times we compare, for example, low_value_e to + space_value_e = 4, + quote_value_e = 5, // + high_value_e = 6, // high_value_e to determine that low is less than high + }; +#define FIGCONST_MASK (figconst_1_e|figconst_2_e|figconst_4_e) +#define DATASECT_MASK (linkage_e | local_e) + + +enum cbl_file_org_t { + file_disorganized_e, + file_sequential_e, + file_line_sequential_e, + file_indexed_e, + file_relative_e, +}; + +enum cbl_file_access_t { + file_inaccessible_e, + file_access_seq_e, + file_access_rnd_e, + file_access_dyn_e, +}; + +enum cbl_file_mode_t { + file_mode_none_e, + file_mode_input_e = 'r', + file_mode_output_e = 'w', + file_mode_extend_e = 'a', + file_mode_io_e = '+', +}; + +enum cbl_round_t { + away_from_zero_e, + nearest_toward_zero_e, + toward_greater_e, + toward_lesser_e, + nearest_away_from_zero_e, + nearest_even_e, + prohibited_e, + truncation_e, +}; + +#define RELOP_START 0 +enum relop_t { + lt_op = RELOP_START, + le_op, + eq_op, + ne_op, + ge_op, + gt_op, +}; + +#define LOGOP_START 100 +enum logop_t { + not_op = LOGOP_START, + and_op, + or_op, + xor_op, + xnor_op, + true_op, + false_op, +}; + +#define SETOP_START 200 +enum setop_t { + is_op = SETOP_START, +}; + +enum bitop_t { + bit_set_op, // set bit on + bit_clear_op, // set bit off + bit_on_op, // true if bit is on + bit_off_op, // true if bit is off + bit_and_op, + bit_or_op, + bit_xor_op, +}; + +enum file_close_how_t { + file_close_no_how_e = 0x00, + file_close_removal_e = 0x01, + file_close_no_rewind_e = 0x02, + file_close_with_lock_e = 0x04, + file_close_reel_unit_e = 0x08, +}; + +enum cbl_compute_error_code_t { + compute_error_none = 0x0000, + compute_error_truncate = 0x0001, + compute_error_divide_by_zero = 0x0002, + compute_error_exp_zero_by_zero = 0x0004, + compute_error_exp_zero_by_minus = 0x0008, + compute_error_exp_minus_by_frac = 0x0010, + compute_error_overflow = 0x0020, + compute_error_underflow = 0x0040, +}; + +enum cbl_arith_format_t { + not_expected_e, + no_giving_e, giving_e, + corresponding_e }; + +enum cbl_encoding_t { + ASCII_e, // STANDARD-1 (in caps to avoid conflict with ascii_e in libgcobol.cc) + iso646_e, // STANDARD-2 + EBCDIC_e, // NATIVE or EBCDIC + custom_encoding_e, +}; + +enum cbl_truncation_mode { + trunc_std_e, + trunc_opt_e, + trunc_bin_e, +}; + +enum cbl_inspect_bound_t { + bound_characters_e, + bound_all_e, + bound_first_e, + bound_leading_e, + bound_trailing_e, +}; + +// a SPECIAL-NAME +enum special_name_t { + SYSIN_e, SYSIPT_e, SYSOUT_e, + SYSLIST_e, SYSLST_e, + SYSPUNCH_e, SYSPCH_e, + CONSOLE_e, + C01_e, C02_e, C03_e, C04_e, C05_e, C06_e, + C07_e, C08_e, C09_e, C10_e, C11_e, C12_e, + CSP_e, + S01_e, S02_e, S03_e, S04_e, S05_e, + AFP_5A_e, + STDIN_e, STDOUT_e, STDERR_e, SYSERR_e, + ARG_NUM_e, ARG_VALUE_e, ENV_NAME_e, ENV_VALUE_e, +}; + +enum classify_t { + ClassInvalidType, + ClassNumericType, + ClassAlphabeticType, + ClassLowerType, + ClassUpperType, + ClassDbcsType, + ClassKanjiType, +}; + +static inline const char * +classify_str( enum classify_t classify ) { + switch(classify) { + case ClassInvalidType: return "ClassInvalidType"; + case ClassNumericType: return "ClassNumericType"; + case ClassAlphabeticType: return "ClassAlphabeticType"; + case ClassLowerType: return "ClassLowerType"; + case ClassUpperType: return "ClassUpperType"; + case ClassDbcsType: return "ClassDbcsType"; + case ClassKanjiType: return "ClassKanjiType"; + }; + return "(unknown classification)"; +} + +static inline const char * +cbl_file_mode_str( cbl_file_mode_t mode ) { + switch(mode) { + case file_mode_none_e: return "file_mode_none_e"; + case file_mode_input_e: return "file_mode_input_e: 'r'"; + case file_mode_output_e: return "file_mode_output_e: 'w'"; + case file_mode_io_e: return "file_mode_io_e: '+'"; + case file_mode_extend_e: return "file_mode_extend_e: 'a'"; + } + return "???"; +}; + +enum module_type_t { + module_activating_e, + module_current_e, + module_nested_e, + module_stack_e, + module_toplevel_e, +}; + + +static inline bool +ec_cmp( ec_type_t raised, ec_type_t mask ) +{ + if( raised == mask ) return true; + + // Do not match on only the low byte. + if( 0 < (~EC_ALL_E & static_cast(mask)) ) return false; + + return 0 != ( static_cast(raised) + & + static_cast(mask) ); +} + +struct cbl_enabled_exception_t { + bool enabled, location; + ec_type_t ec; + size_t file; + + cbl_enabled_exception_t() + : enabled(false) + , location(false) + , ec(ec_none_e) + , file(0) + {} + + cbl_enabled_exception_t( bool enabled, bool location, + ec_type_t ec, size_t file = 0 ) + : enabled(enabled) + , location(location) + , ec(ec) + , file(file) + {} + + // sort by ec and file, not enablement + bool operator<( const cbl_enabled_exception_t& that ) const { + if( ec == that.ec ) return file < that.file; + return ec < that.ec; + } + // match on ec and file, not enablement + bool operator==( const cbl_enabled_exception_t& that ) const { + return ec == that.ec && file == that.file; + } +}; + + +class cbl_enabled_exceptions_array_t; + +class cbl_enabled_exceptions_t : protected std::set +{ + friend cbl_enabled_exceptions_array_t; + void apply( const cbl_enabled_exception_t& elem ) { + auto inserted = insert( elem ); + if( ! inserted.second ) { + erase(inserted.first); + insert(elem); + } + } + + public: + bool turn_on_off( bool enabled, bool location, ec_type_t type, + std::set files ); + + const cbl_enabled_exception_t * match( ec_type_t type, size_t file = 0 ); + + void dump() const; + + void clear() { std::set::clear(); } + + bool empty() const { return std::set::empty(); } + size_t size() const { return std::set::size(); } + + cbl_enabled_exceptions_t& operator=( const cbl_enabled_exceptions_t& that ) { + std::set& self(*this); + self = that; + return *this; + } +}; + +extern cbl_enabled_exceptions_t enabled_exceptions; + +/* + * This class is passed to the runtime function evaluating the raised exception. + * It is constructed in genapi.cc from the compile-time table. + */ +struct cbl_enabled_exceptions_array_t { + size_t nec; + cbl_enabled_exception_t *ecs; + + cbl_enabled_exceptions_array_t( size_t nec, cbl_enabled_exception_t *ecs ) + : nec(nec), ecs(ecs) {} + + cbl_enabled_exceptions_array_t( const cbl_enabled_exceptions_t& input = + cbl_enabled_exceptions_t() ) + : nec(input.size()) + , ecs(NULL) + { + if( ! input.empty() ) { + ecs = new cbl_enabled_exception_t[nec]; + std::copy(input.begin(), input.end(), ecs); + } + } + + cbl_enabled_exceptions_array_t& + operator=( const cbl_enabled_exceptions_array_t& input); + + + bool match( ec_type_t ec, size_t file = 0 ) const; + + size_t nbytes() const { return nec * sizeof(ecs[0]); } +}; + +template +T enabled_exception_match( T beg, T end, ec_type_t type, size_t file ) { + cbl_enabled_exception_t input( true, true, // don't matter + type, file ); + auto output = std::find(beg, end, input); + if( output == end ) { + output = std::find_if( beg, end, // match any file + [ec = type]( const cbl_enabled_exception_t& elem ) { + return + elem.file == 0 && + ec_cmp(ec, elem.ec); } ); + } + return output; +} + + + +#endif diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in new file mode 100644 index 00000000000..c9095ff8906 --- /dev/null +++ b/libgcobol/config.h.in @@ -0,0 +1,100 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if the target assembler supports thread-local storage. */ +#undef HAVE_CC_TLS + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE diff --git a/libgcobol/configure b/libgcobol/configure new file mode 100755 index 00000000000..071f1fc2260 --- /dev/null +++ b/libgcobol/configure @@ -0,0 +1,19627 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for package-unused version-unused. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='package-unused' +PACKAGE_TARNAME='libgcobol' +PACKAGE_VERSION='version-unused' +PACKAGE_STRING='package-unused version-unused' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="Makefile.am" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_unique_file="Makefile.am" +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +extra_darwin_ldflags_libgcobol +get_gcc_base_ver +VERSION_SUFFIX +LIBGCOBOL_VERSION +SPEC_LIBGCOBOL_DEPS +CC_FOR_BUILD +enable_static +enable_shared +ENABLE_DARWIN_AT_RPATH_FALSE +ENABLE_DARWIN_AT_RPATH_TRUE +CXXCPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +OBJDUMP +LN_S +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +RANLIB +NM +AR +am__fastdepCCAS_FALSE +am__fastdepCCAS_TRUE +CCASDEPMODE +CCASFLAGS +CCAS +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +toolexeclibdir +toolexecdir +MAINT +slibdir +BUILD_LIBGCOBOL_FALSE +BUILD_LIBGCOBOL_TRUE +target_subdir +host_subdir +build_subdir +build_libsubdir +target_noncanonical +host_noncanonical +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +multi_basedir +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_multilib +enable_dependency_tracking +enable_silent_rules +with_cross_host +with_build_libsubdir +with_toolexeclibdir +enable_version_specific_runtime_libs +with_slibdir +enable_maintainer_mode +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +enable_darwin_at_rpath +with_gcc_major_version_only +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures package-unused version-unused to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libgcobol] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of package-unused version-unused:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-multilib build many library versions (default) + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-darwin-at-rpath + install libraries with @rpath/library-name, requires + rpaths to be added to executables + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-cross-host=HOST Configuring with a cross compiler + --with-build-libsubdir=DIR Directory where to find libraries for build system + --with-toolexeclibdir=DIR + install libraries built with a cross compiler within + DIR + --with-slibdir=DIR shared libraries in DIR LIBDIR + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-gcc-major-version-only + use only GCC major number in filesystem paths + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CCAS assembler compiler command (defaults to CC) + CCASFLAGS assembler compiler flags (defaults to CFLAGS) + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +package-unused configure version-unused +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by package-unused $as_me version-unused, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + +ac_config_headers="$ac_config_headers config.h" + + +# Default to --enable-multilib +# Check whether --enable-multilib was given. +if test "${enable_multilib+set}" = set; then : + enableval=$enable_multilib; case "$enableval" in + yes) multilib=yes ;; + no) multilib=no ;; + *) as_fn_error $? "bad value $enableval for multilib option" "$LINENO" 5 ;; + esac +else + multilib=yes +fi + + +# We may get other options which we leave undocumented: +# --with-target-subdir, --with-multisrctop, --with-multisubdir +# See config-ml.in if you want the gory details. + +if test "$srcdir" = "."; then + if test "$with_target_subdir" != "."; then + multi_basedir="$srcdir/$with_multisrctop../.." + else + multi_basedir="$srcdir/$with_multisrctop.." + fi +else + multi_basedir="$srcdir/.." +fi + + +# Even if the default multilib is not a cross compilation, +# it may be that some of the other multilibs are. +if test $cross_compiling = no && test $multilib = yes \ + && test "x${with_multisubdir}" != x ; then + cross_compiling=maybe +fi + +ac_config_commands="$ac_config_commands default-1" + + +# This works around the fact that libtool configuration may change LD +# for this particular configuration, but some shells, instead of +# keeping the changes in LD private, export them just because LD is +# exported. +ORIGINAL_LD_FOR_MULTILIBS=$LD + +####. ${srcdir}/configure.tgt + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +printf ("hello world\n"); + ; + return 0; +} +_ACEOF +# FIXME: Cleanup? +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + gcc_no_link=no +else + gcc_no_link=yes +fi +if test x$gcc_no_link = xyes; then + # Setting cross_compile will disable run tests; it will + # also disable AC_CHECK_FILE but that's generally + # correct if we can't link. + cross_compiling=yes + EXEEXT= +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + +# Do not delete or change the following two lines. For why, see +# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +target_alias=${target_alias-$host_alias} + + +am__api_version='1.15' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libgcobol' + VERSION='version-unused' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + # ([1.15.1 no-define foreign no-dist -Wall -Wno-portability]) + + + + + +# Check whether --with-cross-host was given. +if test "${with_cross_host+set}" = set; then : + withval=$with_cross_host; +fi + + +# Checks for header files. +for ac_header in malloc.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default" +if test "x$ac_cv_header_malloc_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MALLOC_H 1 +_ACEOF + +fi + +done + + + + case ${build_alias} in + "") build_noncanonical=${build} ;; + *) build_noncanonical=${build_alias} ;; +esac + + case ${host_alias} in + "") host_noncanonical=${build_noncanonical} ;; + *) host_noncanonical=${host_alias} ;; +esac + + + + case ${target_alias} in + "") target_noncanonical=${host_noncanonical} ;; + *) target_noncanonical=${target_alias} ;; +esac + + + + +# post-stage1 host modules use a different CC_FOR_BUILD so, in order to +# have matching libraries, they should use host libraries: Makefile.tpl +# arranges to pass --with-build-libsubdir=$(HOST_SUBDIR). +# However, they still use the build modules, because the corresponding +# host modules (e.g. bison) are only built for the host when bootstrap +# finishes. So: +# - build_subdir is where we find build modules, and never changes. +# - build_libsubdir is where we find build libraries, and can be overridden. + +# Prefix 'build-' so this never conflicts with target_subdir. +build_subdir="build-${build_noncanonical}" + +# Check whether --with-build-libsubdir was given. +if test "${with_build_libsubdir+set}" = set; then : + withval=$with_build_libsubdir; build_libsubdir="$withval" +else + build_libsubdir="$build_subdir" +fi + +# --srcdir=. covers the toplevel, while "test -d" covers the subdirectories +if ( test $srcdir = . && test -d gcc ) \ + || test -d $srcdir/../host-${host_noncanonical}; then + host_subdir="host-${host_noncanonical}" +else + host_subdir=. +fi +# No prefix. +target_subdir=${target_noncanonical} + + +# ----------------- +# __int128 support +# ----------------- + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __int128 is supported" >&5 +$as_echo_n "checking whether __int128 is supported... " >&6; } +if ${libgcobol_cv_have_int128+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test x$gcc_no_link = xyes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + __int128 foo (__int128 ) + { + __int128 aaa; + return (__int128) aaa; + } + + __int128 bar (__int128 ) + { + __int128 aaa; + return (__int128) aaa; + } + +int +main () +{ + + foo (1); + bar (1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + libgcobol_cv_have_int128=yes + +else + + libgcobol_cv_have_int128=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + __int128 foo (__int128 ) + { + __int128 aaa; + return (__int128) aaa; + } + + __int128 bar (__int128 ) + { + __int128 aaa; + return (__int128) aaa; + } + +int +main () +{ + + foo (1); + bar (1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + libgcobol_cv_have_int128=yes + +else + + libgcobol_cv_have_int128=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcobol_cv_have_int128" >&5 +$as_echo "$libgcobol_cv_have_int128" >&6; } +# The following conditional is useful when this creates a Makefile.am file that +# is subsequently processed into a Makefile.in file. At the present time, +# however the libgcobol build uses a hardcoded Makefile.in file. + if test "x$libgcobol_cv_have_int128" = xyes; then + BUILD_LIBGCOBOL_TRUE= + BUILD_LIBGCOBOL_FALSE='#' +else + BUILD_LIBGCOBOL_TRUE='#' + BUILD_LIBGCOBOL_FALSE= +fi + + + +# Check whether --with-toolexeclibdir was given. +if test "${with_toolexeclibdir+set}" = set; then : + withval=$with_toolexeclibdir; case ${with_toolexeclibdir} in + /) + ;; + */) + with_toolexeclibdir=`echo $with_toolexeclibdir | sed 's,/$,,'` + ;; +esac +else + with_toolexeclibdir=no +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-version-specific-runtime-libs" >&5 +$as_echo_n "checking for --enable-version-specific-runtime-libs... " >&6; } +# Check whether --enable-version-specific-runtime-libs was given. +if test "${enable_version_specific_runtime_libs+set}" = set; then : + enableval=$enable_version_specific_runtime_libs; case "$enableval" in + yes) version_specific_libs=yes ;; + no) version_specific_libs=no ;; + *) as_fn_error $? "Unknown argument to enable/disable version-specific libs" "$LINENO" 5;; + esac +else + version_specific_libs=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $version_specific_libs" >&5 +$as_echo "$version_specific_libs" >&6; } + + +# Check whether --with-slibdir was given. +if test "${with_slibdir+set}" = set; then : + withval=$with_slibdir; slibdir="$with_slibdir" +else + if test "${version_specific_libs}" = yes; then + slibdir='$(libsubdir)' +elif test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then + slibdir='$(exec_prefix)/$(host_noncanonical)/lib' +else + slibdir='$(libdir)' +fi +fi + + + +# Command-line options. +# Very limited version of AC_MAINTAINER_MODE. +# Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; case ${enable_maintainer_mode} in + yes) MAINT='' ;; + no) MAINT='#' ;; + *) as_fn_error $? "--enable-maintainer-mode must be yes or no" "$LINENO" 5 ;; + esac + maintainer_mode=${enableval} +else + MAINT='#' +fi + + +toolexecdir=no +toolexeclibdir=no + +# Calculate toolexeclibdir +# Also toolexecdir, though it's only used in toolexeclibdir +case ${version_specific_libs} in + yes) + # Need the gcc compiler version to know where to install libraries + # and header files if --enable-version-specific-runtime-libs option + # is selected. + toolexecdir='$(libdir)/gcc/$(target_noncanonical)' + toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)' + ;; + no) + if test -n "$with_cross_host" && + test x"$with_cross_host" != x"no"; then + # Install a library built with a cross compiler in tooldir, not libdir. + toolexecdir='$(exec_prefix)/$(target_noncanonical)' + toolexeclibdir='$(toolexecdir)/lib' + else + toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)' + toolexeclibdir='$(libdir)' + fi + multi_os_directory=`$CC -print-multi-os-directory` + case $multi_os_directory in + .) ;; # Avoid trailing /. + *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; + esac + ;; +esac + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# Check the compiler. +# The same as in boehm-gc and libstdc++. Have to borrow it from there. +# We must force CC to /not/ be precious variables; otherwise +# the wrong, non-multilib-adjusted value will be used in multilibs. +# As a side effect, we have to subst CFLAGS ourselves. + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +# By default we simply use the C compiler to build assembly code. + +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + + + +depcc="$CCAS" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CCAS_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CCAS_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CCAS_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; } +CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then + am__fastdepCCAS_TRUE= + am__fastdepCCAS_FALSE='#' +else + am__fastdepCCAS_TRUE='#' + am__fastdepCCAS_FALSE= +fi + + + + + + +# In order to override CFLAGS_FOR_TARGET, all of our special flags go +# in XCFLAGS. But we need them in CFLAGS during configury. So put them +# in both places for now and restore CFLAGS at the end of config. +save_CFLAGS="$CFLAGS" + +# Find other programs we need. +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +$as_echo "$NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NM="nm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5 +$as_echo "$ac_ct_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +else + NM="$ac_cv_prog_NM" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB="ranlib-not-found-in-path-error" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.7a' +macro_revision='1.3134' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`print -r -- -n 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the nm to test. + lt_nm_to_check="$NM" + else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + fi + for lt_tmp_nm in "$lt_nm_to_check"; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + # Strip out any user-provided options from the nm to test twice, + # the first time to test to see if nm (rather than its options) has + # an explicit path, the second time to yield a file which can be + # nm'ed itself. + tmp_nm_path="`$ECHO "$lt_tmp_nm" | sed 's, -.*$,,'`" + case "$tmp_nm_path" in + */*|*\\*) tmp_nm="$lt_tmp_nm";; + *) tmp_nm="$ac_dir/$lt_tmp_nm";; + esac + tmp_nm_to_nm="`$ECHO "$tmp_nm" | sed 's, -.*$,,'`" + if test -f "$tmp_nm_to_nm" || test -f "$tmp_nm_to_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + case `"$tmp_nm" -B "$tmp_nm_to_nm" 2>&1 | grep -v '^ *$' | sed '1q'` in + *$tmp_nm*) lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p "$tmp_nm_to_nm" 2>&1 | grep -v '^ *$' | sed '1q'` in + *$tmp_nm*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +vxworks*) + # Assume VxWorks cross toolchains are built on Linux, possibly + # as canadian for Windows hosts. + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +plugin_option= +plugin_names="liblto_plugin.so liblto_plugin-0.dll cyglto_plugin-0.dll" +for plugin in $plugin_names; do + plugin_so=`${CC} ${CFLAGS} --print-prog-name $plugin` + if test x$plugin_so = x$plugin; then + plugin_so=`${CC} ${CFLAGS} --print-file-name $plugin` + fi + if test x$plugin_so != x$plugin; then + plugin_option="--plugin $plugin_so" + break + fi +done + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +if test -n "$plugin_option"; then + if $AR --help 2>&1 | grep -q "\--plugin"; then + touch conftest.c + $AR $plugin_option rc conftest.a conftest.c + if test "$?" != 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5 +$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;} + else + AR="$AR $plugin_option" + fi + rm -f conftest.* + fi +fi +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: +if test -n "$plugin_option" && test "$RANLIB" != ":"; then + if $RANLIB --help 2>&1 | grep -q "\--plugin"; then + RANLIB="$RANLIB $plugin_option" + fi +fi + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BCDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + # Allow for Darwin 4-7 (macOS 10.0-10.3) although these are not expect to + # build without first building modern cctools / linker. + case $host_cpu-$host_os in + *-rhapsody* | *-darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + *-darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + *-darwin*) + # darwin 5.x (macOS 10.1) onwards we only need to adjust when the + # deployment target is forced to an earlier version. + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in + UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) + ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + *) + ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + + # Publish an arg to allow the user to select that Darwin host (and target) + # libraries should be given install-names like @rpath/libfoo.dylib. This + # requires that the user of the library then adds an 'rpath' to the DSO that + # needs access. + # NOTE: there are defaults below, for systems that support rpaths. The person + # configuring can override the defaults for any system version that supports + # them - they are, however, forced off for system versions without support. + # Check whether --enable-darwin-at-rpath was given. +if test "${enable_darwin_at_rpath+set}" = set; then : + enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then + # This is not supported before macOS 10.5 / Darwin9. + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in + UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 +$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} + enable_darwin_at_rpath=no + ;; + esac + fi +else + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in + # As above, before 10.5 / Darwin9 this does not work. + UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) + enable_darwin_at_rpath=no + ;; + + # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use + # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key + # system executables (e.g. /bin/sh). Force rpaths on for these systems. + UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 +$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} + enable_darwin_at_rpath=yes + ;; + # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can + # work with either DYLD_LIBRARY_PATH or embedded rpaths. + + esac + +fi + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _lt_install_name='\$rpath/\$soname' + if test "x$enable_darwin_at_rpath" = "xyes"; then + _lt_install_name='@rpath/\$soname' + fi + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo(void) {} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. + +# uclinux* changes (here and below) have been submitted to the libtool +# project, but have not yet been accepted: they are GCC-local changes +# for the time being. (See +# https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | uclinuxfdpiceabi) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +# Shared libraries for VwWorks, >= 7 only at this stage +# and (fpic) still incompatible with "large" code models +# in a few configurations. Only for RTP mode in any case, +# and upon explicit request at configure time. +vxworks7*) + dynamic_linker=no + case ${with_multisubdir}-${enable_shared} in + *large*) + ;; + *mrtp*-yes) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker="$host_os module_loader" + ;; + esac + ;; +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 12660 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 12766 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + + + + # Publish an arg to allow the user to select that Darwin host (and target) + # libraries should be given install-names like @rpath/libfoo.dylib. This + # requires that the user of the library then adds an 'rpath' to the DSO that + # needs access. + # NOTE: there are defaults below, for systems that support rpaths. The person + # configuring can override the defaults for any system version that supports + # them - they are, however, forced off for system versions without support. + # Check whether --enable-darwin-at-rpath was given. +if test "${enable_darwin_at_rpath+set}" = set; then : + enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then + # This is not supported before macOS 10.5 / Darwin9. + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in + UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 +$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} + enable_darwin_at_rpath=no + ;; + esac + fi +else + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in + # As above, before 10.5 / Darwin9 this does not work. + UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) + enable_darwin_at_rpath=no + ;; + + # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use + # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key + # system executables (e.g. /bin/sh). Force rpaths on for these systems. + UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 +$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} + enable_darwin_at_rpath=yes + ;; + # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can + # work with either DYLD_LIBRARY_PATH or embedded rpaths. + + esac + +fi + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _lt_install_name='\$rpath/\$soname' + if test "x$enable_darwin_at_rpath" = "xyes"; then + _lt_install_name='@rpath/\$soname' + fi + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _lt_install_name='\$rpath/\$soname' + if test "x$enable_darwin_at_rpath" = "xyes"; then + _lt_install_name='@rpath/\$soname' + fi + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # For VxWorks ports, we assume the use of a GNU linker with + # standard elf conventions. + ld_shlibs_CXX=yes + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_prog_compiler_pic_CXX" >&6; } + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. + +# uclinux* changes (here and below) have been submitted to the libtool +# project, but have not yet been accepted: they are GCC-local changes +# for the time being. (See +# https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | uclinuxfdpiceabi) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +# Shared libraries for VwWorks, >= 7 only at this stage +# and (fpic) still incompatible with "large" code models +# in a few configurations. Only for RTP mode in any case, +# and upon explicit request at configure time. +vxworks7*) + dynamic_linker=no + case ${with_multisubdir}-${enable_shared} in + *large*) + ;; + *mrtp*-yes) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker="$host_os module_loader" + ;; + esac + ;; +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + +enable_dlopen=yes + + + + + if test x$enable_darwin_at_rpath = xyes; then + ENABLE_DARWIN_AT_RPATH_TRUE= + ENABLE_DARWIN_AT_RPATH_FALSE='#' +else + ENABLE_DARWIN_AT_RPATH_TRUE='#' + ENABLE_DARWIN_AT_RPATH_FALSE= +fi + + + + + +if test "${multilib}" = "yes"; then + multilib_arg="--enable-multilib" +else + multilib_arg= +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Check the compiler. +# The same as in boehm-gc and libstdc++. Have to borrow it from there. +# We must force CC to /not/ be precious variables; otherwise +# the wrong, non-multilib-adjusted value will be used in multilibs. +# As a side effect, we have to subst CFLAGS ourselves. + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + +CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing malloc" >&5 +$as_echo_n "checking for library containing malloc... " >&6; } +if ${ac_cv_search_malloc+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char malloc (); +int +main () +{ +return malloc (); + ; + return 0; +} +_ACEOF +for ac_lib in '' c; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_malloc=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_malloc+:} false; then : + break +fi +done +if ${ac_cv_search_malloc+:} false; then : + +else + ac_cv_search_malloc=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_malloc" >&5 +$as_echo "$ac_cv_search_malloc" >&6; } +ac_res=$ac_cv_search_malloc +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing cosf" >&5 +$as_echo_n "checking for library containing cosf... " >&6; } +if ${ac_cv_search_cosf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char cosf (); +int +main () +{ +return cosf (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_cosf=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_cosf+:} false; then : + break +fi +done +if ${ac_cv_search_cosf+:} false; then : + +else + ac_cv_search_cosf=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_cosf" >&5 +$as_echo "$ac_cv_search_cosf" >&6; } +ac_res=$ac_cv_search_cosf +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +$as_echo_n "checking for library containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_clock_gettime+:} false; then : + break +fi +done +if ${ac_cv_search_clock_gettime+:} false; then : + +else + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +# Add dependencies for libgcobol.spec file +SPEC_LIBGCOBOL_DEPS="$LIBS" + + +# libgcobol soname version +LIBGCOBOL_VERSION=1:0:0 + + +## added +VERSION_SUFFIX=$(echo $LIBGCOBOL_VERSION | tr ':' '.' ) + +## end added + +# Determine what GCC version number to use in filesystem paths. + + get_gcc_base_ver="cat" + +# Check whether --with-gcc-major-version-only was given. +if test "${with_gcc_major_version_only+set}" = set; then : + withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" + fi + +fi + + + + +extra_darwin_ldflags_libgcobol= +case $host in + *-*-darwin*) + extra_darwin_ldflags_libgcobol=-Wl,-U,___cobol_main ;; + *) ;; +esac + + + +ac_config_files="$ac_config_files Makefile" + +####AC_CONFIG_FILES(libgcobol.spec) + +{ $as_echo "$as_me:${as_lineno-$LINENO}: libgcobol has been configured." >&5 +$as_echo "$as_me: libgcobol has been configured." >&6;} + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${BUILD_LIBGCOBOL_TRUE}" && test -z "${BUILD_LIBGCOBOL_FALSE}"; then + as_fn_error $? "conditional \"BUILD_LIBGCOBOL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by package-unused $as_me version-unused, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +package-unused config.status version-unused +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# + +srcdir="$srcdir" +host="$host" +target="$target" +with_multisubdir="$with_multisubdir" +with_multisrctop="$with_multisrctop" +with_target_subdir="$with_target_subdir" +ac_configure_args="${multilib_arg} ${ac_configure_args}" +multi_basedir="$multi_basedir" +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +CC="$CC" +CXX="$CXX" +GFORTRAN="$GFORTRAN" +GDC="$GDC" +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +fix_srcfile_path_CXX='`$ECHO "$fix_srcfile_path_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +fix_srcfile_path_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "default-1":C) +# Only add multilib support code if we just rebuilt the top-level +# Makefile. +case " $CONFIG_FILES " in + *" Makefile "*) + ac_file=Makefile . ${multi_basedir}/config-ml.in + ;; +esac ;; + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac new file mode 100644 index 00000000000..08ad19345b2 --- /dev/null +++ b/libgcobol/configure.ac @@ -0,0 +1,268 @@ +# Configure script for libgcobol. +# Adapted by James K. Lowden from configure script for libalg68. + +# This file is part of GCC. + +# GCC 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 3, or (at your option) +# any later version. + +# GCC 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 GCC; see the file COPYING3. If not see +# . + +# Configure looks for the existence of this file to auto-config each language. +# We define several parameters used by configure: + +# Process this file with autoreconf to produce a configure script. + +AC_INIT(package-unused, version-unused,,libgcobol) +AC_CONFIG_SRCDIR(Makefile.am) +AC_CONFIG_HEADER(config.h) + +AM_ENABLE_MULTILIB(, ..) + +# This works around the fact that libtool configuration may change LD +# for this particular configuration, but some shells, instead of +# keeping the changes in LD private, export them just because LD is +# exported. +ORIGINAL_LD_FOR_MULTILIBS=$LD + +####. ${srcdir}/configure.tgt + +GCC_NO_EXECUTABLES + +AC_USE_SYSTEM_EXTENSIONS + +# Do not delete or change the following two lines. For why, see +# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html +AC_CANONICAL_SYSTEM +target_alias=${target_alias-$host_alias} +AC_SUBST(target_alias) + +AM_INIT_AUTOMAKE # ([1.15.1 no-define foreign no-dist -Wall -Wno-portability]) + +AH_TEMPLATE(PACKAGE, [Name of package]) +AH_TEMPLATE(VERSION, [Version number of package]) + +AC_ARG_WITH(cross-host, +[ --with-cross-host=HOST Configuring with a cross compiler]) + +# Checks for header files. +AC_CHECK_HEADERS(malloc.h) + +AC_CANONICAL_HOST +ACX_NONCANONICAL_HOST +ACX_NONCANONICAL_TARGET +GCC_TOPLEV_SUBDIRS + +# ----------------- +# __int128 support +# ----------------- + +AC_CACHE_CHECK([whether __int128 is supported], [libgcobol_cv_have_int128], + [GCC_TRY_COMPILE_OR_LINK([ + __int128 foo (__int128 ) + { + __int128 aaa; + return (__int128) aaa; + } + + __int128 bar (__int128 ) + { + __int128 aaa; + return (__int128) aaa; + } + ],[ + foo (1); + bar (1); + ],[ + libgcobol_cv_have_int128=yes + ],[ + libgcobol_cv_have_int128=no +])]) +# The following conditional is useful when this creates a Makefile.am file that +# is subsequently processed into a Makefile.in file. At the present time, +# however the libgcobol build uses a hardcoded Makefile.in file. +AM_CONDITIONAL(BUILD_LIBGCOBOL, [test "x$libgcobol_cv_have_int128" = xyes]) + +GCC_WITH_TOOLEXECLIBDIR + +AC_MSG_CHECKING([for --enable-version-specific-runtime-libs]) +AC_ARG_ENABLE(version-specific-runtime-libs, +[ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory ], +[case "$enableval" in + yes) version_specific_libs=yes ;; + no) version_specific_libs=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);; + esac], +[version_specific_libs=no]) +AC_MSG_RESULT($version_specific_libs) + +AC_ARG_WITH(slibdir, +[ --with-slibdir=DIR shared libraries in DIR [LIBDIR]], +slibdir="$with_slibdir", +if test "${version_specific_libs}" = yes; then + slibdir='$(libsubdir)' +elif test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then + slibdir='$(exec_prefix)/$(host_noncanonical)/lib' +else + slibdir='$(libdir)' +fi) +AC_SUBST(slibdir) + +# Command-line options. +# Very limited version of AC_MAINTAINER_MODE. +AC_ARG_ENABLE([maintainer-mode], + [AC_HELP_STRING([--enable-maintainer-mode], + [enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer])], + [case ${enable_maintainer_mode} in + yes) MAINT='' ;; + no) MAINT='#' ;; + *) AC_MSG_ERROR([--enable-maintainer-mode must be yes or no]) ;; + esac + maintainer_mode=${enableval}], + [MAINT='#']) +AC_SUBST([MAINT])dnl + +toolexecdir=no +toolexeclibdir=no + +# Calculate toolexeclibdir +# Also toolexecdir, though it's only used in toolexeclibdir +case ${version_specific_libs} in + yes) + # Need the gcc compiler version to know where to install libraries + # and header files if --enable-version-specific-runtime-libs option + # is selected. + toolexecdir='$(libdir)/gcc/$(target_noncanonical)' + toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)' + ;; + no) + if test -n "$with_cross_host" && + test x"$with_cross_host" != x"no"; then + # Install a library built with a cross compiler in tooldir, not libdir. + toolexecdir='$(exec_prefix)/$(target_noncanonical)' + toolexeclibdir='$(toolexecdir)/lib' + else + toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)' + toolexeclibdir='$(libdir)' + fi + multi_os_directory=`$CC -print-multi-os-directory` + case $multi_os_directory in + .) ;; # Avoid trailing /. + *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; + esac + ;; +esac + +AC_SUBST(toolexecdir) +AC_SUBST(toolexeclibdir) + +AH_TEMPLATE(PACKAGE, [Name of package]) +AH_TEMPLATE(VERSION, [Version number of package]) + +AM_MAINTAINER_MODE + +# Check the compiler. +# The same as in boehm-gc and libstdc++. Have to borrow it from there. +# We must force CC to /not/ be precious variables; otherwise +# the wrong, non-multilib-adjusted value will be used in multilibs. +# As a side effect, we have to subst CFLAGS ourselves. + +m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) +m4_define([_AC_ARG_VAR_PRECIOUS],[]) +AC_PROG_CC +AC_PROG_CXX +AM_PROG_AS +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) + +AC_SUBST(CFLAGS) + +# In order to override CFLAGS_FOR_TARGET, all of our special flags go +# in XCFLAGS. But we need them in CFLAGS during configury. So put them +# in both places for now and restore CFLAGS at the end of config. +save_CFLAGS="$CFLAGS" + +# Find other programs we need. +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(NM, nm) +AC_CHECK_TOOL(RANLIB, ranlib, ranlib-not-found-in-path-error) +AC_PROG_MAKE_SET +AC_PROG_INSTALL + +AM_PROG_LIBTOOL +LT_INIT + +AC_LIBTOOL_DLOPEN + +AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + +AC_SUBST(enable_shared) +AC_SUBST(enable_static) + +if test "${multilib}" = "yes"; then + multilib_arg="--enable-multilib" +else + multilib_arg= +fi + +AC_LANG_C +# Check the compiler. +# The same as in boehm-gc and libstdc++. Have to borrow it from there. +# We must force CC to /not/ be precious variables; otherwise +# the wrong, non-multilib-adjusted value will be used in multilibs. +# As a side effect, we have to subst CFLAGS ourselves. + +m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) +m4_define([_AC_ARG_VAR_PRECIOUS],[]) +AC_PROG_CC +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) + +AC_SUBST(CFLAGS) + +CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} +AC_SUBST(CC_FOR_BUILD) + +AC_SEARCH_LIBS([malloc], [c]) +AC_SEARCH_LIBS([cosf], [m]) +AC_SEARCH_LIBS([clock_gettime], [rt]) + +# Add dependencies for libgcobol.spec file +SPEC_LIBGCOBOL_DEPS="$LIBS" +AC_SUBST(SPEC_LIBGCOBOL_DEPS) + +# libgcobol soname version +LIBGCOBOL_VERSION=1:0:0 +AC_SUBST(LIBGCOBOL_VERSION) + +## added +VERSION_SUFFIX=$(echo $LIBGCOBOL_VERSION | tr ':' '.' ) +AC_SUBST(VERSION_SUFFIX) +## end added + +# Determine what GCC version number to use in filesystem paths. +GCC_BASE_VER + +extra_darwin_ldflags_libgcobol= +case $host in + *-*-darwin*) + extra_darwin_ldflags_libgcobol=-Wl,-U,___cobol_main ;; + *) ;; +esac +AC_SUBST(extra_darwin_ldflags_libgcobol) + +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_FILES([Makefile]) +####AC_CONFIG_FILES(libgcobol.spec) + +AC_MSG_NOTICE([libgcobol has been configured.]) + +AC_OUTPUT diff --git a/libgcobol/configure.tgt b/libgcobol/configure.tgt new file mode 100644 index 00000000000..a64539c919f --- /dev/null +++ b/libgcobol/configure.tgt @@ -0,0 +1,41 @@ +# -*- shell-script -*- +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# GCC 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 3, or (at your option) +# any later version. +# +# GCC 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 GCC; see the file COPYING3. If not see +# . + +# This is the target specific configuration file. This is invoked by the +# autoconf generated configure script. Putting it in a separate shell file +# lets us skip running autoconf when modifying target specific information. + +# Enable the libgcobol build only on systems where it is known to work. +# More targets shall be added after testing. +# For testing, you can override this with --enable-libgcobol. (See configure.ac) + +LIBGCOBOL_SUPPORTED=no + +case "${target}" in + aarch64*-*-linux*) + LIBGCOBOL_SUPPORTED=yes + ;; + powerpc64le-*-linux*) + LIBGCOBOL_SUPPORTED=yes + ;; + x86_64-*-linux*x32) + LIBGCOBOL_SUPPORTED=no + ;; + x86_64-*-linux*) + LIBGCOBOL_SUPPORTED=yes + ;; +esac diff --git a/libgcobol/constants.cc b/libgcobol/constants.cc new file mode 100644 index 00000000000..3b4d68a730b --- /dev/null +++ b/libgcobol/constants.cc @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "io.h" +#include "common-defs.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "gfileio.h" +#include "charmaps.h" + +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wwrite-strings" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + +// There are global variables that need to be initialized at the point where +// the very first PROGRAM-ID is executed. This flag is used to make sure that +// initialization happens just once. +int __gg__globals_are_initialized = 0; + +// We have a number of integer constants. We need two macros, one for 1-digit +// names and a second for 2-digit names in order to match our mangling +// convention for variable names that start with a numeric: + +// 4 becomes _1_4 +// _ indicates this is a mangled name +// 1 means it is one character long +// _ terminates the 1 +// 4 is the one-character name + +#define INTEGER_CONSTANT1(a) \ +unsigned char __gg__data_##a[1] = {(a)}; \ +struct cblc_field_t __gg___1_##a = { \ + .data = __gg__data_##a , \ + .capacity = 1 , \ + .allocated = 1 , \ + .offset = 0 , \ + .name = #a , \ + .picture = "" , \ + .initial = #a , \ + .parent = NULL, \ + .occurs_lower = 0 , \ + .occurs_upper = 0 , \ + .attr = 0x80 , \ + .type = FldLiteralN , \ + .level = 0 , \ + .digits = 0 , \ + .rdigits = 0 , \ + .dummy = 0 , \ + }; + +#define INTEGER_CONSTANT2(a) \ +unsigned char __gg__data_##a[1] = {(a)}; \ +struct cblc_field_t __gg___2_##a = { \ + .data = __gg__data_##a , \ + .capacity = 1 , \ + .allocate = 1 , \ + .offset = 0 , \ + .name = #a , \ + .picture = "" , \ + .initial = #a , \ + .parent = NULL, \ + .occurs_lower = 0 , \ + .occurs_upper = 0 , \ + .attr = 0x80 , \ + .type = FldLiteralN , \ + .level = 0 , \ + .digits = 0 , \ + .rdigits = 0 , \ + .dummy = 0 , \ + }; + + + +unsigned char __gg__data_space[1] = {' '}; +struct cblc_field_t __gg__space = { + .data = __gg__data_space , + .capacity = sizeof(__gg__data_space) , + .allocated = sizeof(__gg__data_space) , + .offset = 0 , + .name = "SPACE" , + .picture = "" , + .initial = (char *)space_value_e , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x284 , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +struct cblc_field_t __gg__spaces = { + .data = __gg__data_space , + .capacity = sizeof(__gg__data_space) , + .allocated = sizeof(__gg__data_space) , + .offset = 0 , + .name = "SPACES" , + .picture = "" , + .initial = (char *)space_value_e , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x284 , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data_low_values[1] = {'\0'}; +struct cblc_field_t __gg__low_values = { + .data = __gg__data_low_values, + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "LOW_VALUES" , + .picture = "" , + .initial = (char *)low_value_e , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x281 , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data_zeros[1] = {'0'}; +struct cblc_field_t __gg__zeros = { + .data = __gg__data_zeros , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "ZEROS" , + .picture = "" , + .initial = (char *)zero_value_e , + .parent = NULL , + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x83 , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data_high_values[1] = {0xFF}; +struct cblc_field_t __gg__high_values = { + .data = __gg__data_high_values , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "HIGH_VALUES" , + .picture = "" , + .initial = (char *)high_value_e , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x286 , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data_quotes[1] = {0xFF}; +struct cblc_field_t __gg__quotes = { + .data = __gg__data_quotes , + .capacity = 1 , + .allocated = 1 , + .offset = 0 , + .name = "QUOTES" , + .picture = "" , + .initial = (char *)quote_value_e , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x285 , + .type = FldAlphanumeric , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data_nulls[8] = {0,0,0,0,0,0,0,0}; +struct cblc_field_t __gg__nulls = { + .data = __gg__data_nulls , + .capacity = 8 , + .allocated = 8 , + .offset = 0 , + .name = "NULLS" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x280 , + .type = FldPointer , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data__file_status[2] = {0,0}; +struct cblc_field_t __gg___file_status = { + .data = __gg__data__file_status , + .capacity = 2 , + .allocated = 2 , + .offset = 0 , + .name = "_FILE_STATUS" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldNumericDisplay , + .level = 0 , + .digits = 2 , + .rdigits = 0 , + .dummy = 0 , + }; + + +unsigned char __gg__data_linage_counter[2] = {0,0}; +struct cblc_field_t __gg___14_linage_counter6 = { + .data = __gg__data_linage_counter , + .capacity = 2 , + .allocated = 2 , + .offset = 0 , + .name = "LINAGE-COUNTER" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldNumericBin5 , + .level = 0 , + .digits = 4 , + .rdigits = 0 , + .dummy = 0 , + }; + + +unsigned char __gg__data_upsi_0[2] = {0,0}; +struct cblc_field_t __gg___6_upsi_04 = { + .data = __gg__data_upsi_0 , + .capacity = 2 , + .allocated = 2 , + .offset = 0 , + .name = "UPSI-0" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldNumericBin5 , + .level = 0 , + .digits = 4 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg__data_return_code[2] = {0,0}; +struct cblc_field_t __gg___11_return_code6 = { + .data = __gg__data_return_code , + .capacity = 2 , + .allocated = 2 , + .offset = 0 , + .name = "RETURN-CODE" , + .picture = "" , + .initial = "" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldNumericBin5 , + .level = 0 , + .digits = 4 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg___data_dev_stdin[] = "/dev/stdin"; +struct cblc_field_t __gg___dev_stdin = { + .data = __gg___data_dev_stdin , + .capacity = sizeof(__gg___data_dev_stdin)-1 , + .allocated = sizeof(__gg___data_dev_stdin)-1 , + .offset = 0 , + .name = "_dev_stdin" , + .picture = "" , + .initial = "/dev/stdin" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldLiteralA , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + + unsigned char __gg___data_dev_stdout[] = "/dev/stdout"; +struct cblc_field_t __gg___dev_stdout = { + .data = __gg___data_dev_stdout , + .capacity = sizeof(__gg___data_dev_stdout)-1 , + .allocated = sizeof(__gg___data_dev_stdout)-1 , + .offset = 0 , + .name = "_dev_stdout" , + .picture = "" , + .initial = "/dev/stdout" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldLiteralA , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg___data_dev_stderr[] = "/dev/stderr"; +struct cblc_field_t __gg___dev_stderr = { + .data = __gg___data_dev_stderr , + .capacity = sizeof(__gg___data_dev_stderr)-1 , + .allocated = sizeof(__gg___data_dev_stderr)-1 , + .offset = 0 , + .name = "_dev_stderr" , + .picture = "" , + .initial = "/dev/stderr" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldLiteralA , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +unsigned char __gg___data_dev_null[] = "/dev/null"; +struct cblc_field_t __gg___dev_null = { + .data = __gg___data_dev_null , + .capacity = sizeof(__gg___data_dev_null)-1 , + .allocated = sizeof(__gg___data_dev_null)-1 , + .offset = 0 , + .name = "_dev_null" , + .picture = "" , + .initial = "/dev/null" , + .parent = NULL, + .occurs_lower = 0 , + .occurs_upper = 0 , + .attr = 0x0 , + .type = FldLiteralA , + .level = 0 , + .digits = 0 , + .rdigits = 0 , + .dummy = 0 , + }; + +#pragma GCC diagnostic pop + + + + diff --git a/libgcobol/ec.h b/libgcobol/ec.h new file mode 100644 index 00000000000..1e3f7cfa7ea --- /dev/null +++ b/libgcobol/ec.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CBL_EC_H_ +#define _CBL_EC_H_ + +#include +#include + +#define EC_ALL_E 0xFFFFFF00 + +enum ec_type_t { + ec_none_e = 0x00000000, + ec_all_e = EC_ALL_E, // 0xFFFFFF00 + + ec_argument_e = 0x00000100, + ec_argument_function_e, + ec_argument_imp_e, + ec_argument_imp_command_e, + ec_argument_imp_environment_e, + + ec_bound_e = 0x00000200, + ec_bound_func_ret_value_e, + ec_bound_imp_e, + ec_bound_odo_e, + ec_bound_overflow_e, + ec_bound_ptr_e, + ec_bound_ref_mod_e, + ec_bound_set_e, + ec_bound_subscript_e, + ec_bound_table_limit_e, + + ec_data_e = 0x00000400, + ec_data_conversion_e, + ec_data_imp_e, + ec_data_incompatible_e, + ec_data_not_finite_e, + ec_data_overflow_e, + ec_data_ptr_null_e, + + ec_external_e = 0x00000800, + ec_external_data_mismatch_e, + ec_external_file_mismatch_e, + ec_external_format_conflict_e, + + ec_flow_e = 0x00001000, + ec_flow_global_exit_e, + ec_flow_global_goback_e, + ec_flow_imp_e, + ec_flow_release_e, + ec_flow_report_e, + ec_flow_return_e, + ec_flow_search_e, + ec_flow_use_e, + + ec_function_e = 0x00002000, + ec_function_not_found_e, + ec_function_ptr_invalid_e, + ec_function_ptr_null_e, + + ec_io_e = 0x00004000, + ec_io_at_end_e, + ec_io_invalid_key_e, + ec_io_permanent_error_e, + ec_io_logic_error_e, + ec_io_record_operation_e, + ec_io_file_sharing_e, + ec_io_record_content_e, + ec_io_imp_e, + ec_io_eop_e, + ec_io_eop_overflow_e, + ec_io_linage_e, + + ec_imp_e = 0x00008000, + ec_imp_suffix_e, + + ec_locale_e = 0x00010000, + ec_locale_imp_e, + ec_locale_incompatible_e, + ec_locale_invalid_e, + ec_locale_invalid_ptr_e, + ec_locale_missing_e, + ec_locale_size_e, + + ec_oo_e = 0x00020000, + ec_oo_arg_omitted_e, + ec_oo_conformance_e, + ec_oo_exception_e, + ec_oo_imp_e, + ec_oo_method_e, + ec_oo_null_e, + ec_oo_resource_e, + ec_oo_universal_e, + + ec_order_e = 0x00040000, + ec_order_imp_e, + ec_order_not_supported_e, + + ec_overflow_e = 0x00080000, + ec_overflow_imp_e, + ec_overflow_string_e, + ec_overflow_unstring_e, + + ec_program_e = 0x00100000, + ec_program_arg_mismatch_e, + ec_program_arg_omitted_e, + ec_program_cancel_active_e, + ec_program_imp_e, + ec_program_not_found_e, + ec_program_ptr_null_e, + ec_program_recursive_call_e, + ec_program_resources_e, + + ec_raising_e = 0x00200000, + ec_raising_imp_e, + ec_raising_not_specified_e, + + ec_range_e = 0x00400000, + ec_range_imp_e, + ec_range_index_e, + ec_range_inspect_size_e, + ec_range_invalid_e, + ec_range_perform_varying_e, + ec_range_ptr_e, + ec_range_search_index_e, + ec_range_search_no_match_e, + + ec_report_e = 0x00800000, + ec_report_active_e, + ec_report_column_overlap_e, + ec_report_file_mode_e, + ec_report_imp_e, + ec_report_inactive_e, + ec_report_line_overlap_e, + ec_report_not_terminated_e, + ec_report_page_limit_e, + ec_report_page_width_e, + ec_report_sum_size_e, + ec_report_varying_e, + + ec_screen_e = 0x01000000, + ec_screen_field_overlap_e, + ec_screen_imp_e, + ec_screen_item_truncated_e, + ec_screen_line_number_e, + ec_screen_starting_column_e, + + ec_size_e = 0x02000000, + ec_size_address_e, + ec_size_exponentiation_e, + ec_size_imp_e, + ec_size_overflow_e, + ec_size_truncation_e, + ec_size_underflow_e, + ec_size_zero_divide_e, + + ec_sort_merge_e = 0x04000000, + ec_sort_merge_active_e, + ec_sort_merge_file_open_e, + ec_sort_merge_imp_e, + ec_sort_merge_release_e, + ec_sort_merge_return_e, + ec_sort_merge_sequence_e, + + ec_storage_e = 0x08000000, + ec_storage_imp_e, + ec_storage_not_alloc_e, + ec_storage_not_avail_e, + + ec_user_e = 0x10000000, + ec_user_suffix_e, + + ec_validate_e = 0x20000000, + ec_validate_content_e, + ec_validate_format_e, + ec_validate_imp_e, + ec_validate_relation_e, + ec_validate_varying_e, + + ec_continue_e = 0x30000000, + ec_continue_less_than_zero, +}; + + +#endif diff --git a/libgcobol/exceptl.h b/libgcobol/exceptl.h new file mode 100644 index 00000000000..35809034f4f --- /dev/null +++ b/libgcobol/exceptl.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CBL_EXCEPTC_H_ +#define _CBL_EXCEPTC_H_ + +/* This file contains declarations needed by the libgcobol compilation. Some + of the information here is required by the gcc/cobol compilation, and so it + is safe to include in those files. */ + +static const ec_type_t simon_says_important[] = { + ec_argument_function_e, + ec_bound_odo_e, + ec_bound_ref_mod_e, + ec_bound_subscript_e, + ec_data_incompatible_e, + ec_data_ptr_null_e, + ec_size_overflow_e, + ec_size_exponentiation_e, + ec_size_truncation_e, + ec_size_zero_divide_e, + ec_program_not_found_e, + ec_program_recursive_call_e, + ec_program_arg_mismatch_e, +}; + +enum ec_disposition_t { + ec_category_none_e, + ec_category_fatal_e, + ec_category_nonfatal_e, + ec_category_implementor_e, + + // unimplemented equivalents + uc_category_none_e = 0x80 + ec_category_none_e, + uc_category_fatal_e = 0x80 + ec_category_fatal_e, + uc_category_nonfatal_e = 0x80 + ec_category_nonfatal_e, + uc_category_implementor_e = 0x80 + ec_category_implementor_e, +}; + +struct ec_descr_t { + ec_type_t type; + ec_disposition_t disposition; + const cbl_name_t name; + const char *description; + + bool operator==( ec_type_t type ) const { + return this->type == type; + } +}; + +extern ec_type_t ec_type_of( const cbl_name_t name ); + +extern ec_descr_t __gg__exception_table[]; +extern ec_descr_t *__gg__exception_table_end; + +/* Inventory of exceptions: + In except.hc::__gg__exception_table, unimplemented ECs have a uc_ disposition. + + ec_function_argument_e ACOS + ANNUITY + ASIN + LOG + LOG10 + PRESENT-VALUE + SQRT + + ec_sort_merge_file_open_e FILE MERGE + + ec_bound_subscript_e table subscript not an integer + table subscript less than 1 + table subscript greater than occurs + + ec_bound_ref_mod_e refmod start not an integer + refmod start less than 1 + refmod start greater than variable size + refmod length not an integer + refmod length less than 1 + refmod start+length exceeds variable size + + ec_bound_odo_e DEPENDING not an integer + DEPENDING greater than occurs upper limit + DEPENDING less than occurs lower limit + subscript greater than DEPENDING for sending item + + ec_size_zero_divide_e For both fixed-point and floating-point division + + ec_size_truncation + ec_size_exponentiation + + */ + +// SymException +struct cbl_exception_t { + size_t program, file; + ec_type_t type; + cbl_file_mode_t mode; +}; + + +struct cbl_declarative_t { + enum { files_max = 16 }; + size_t section; // implies program + bool global; + ec_type_t type; + uint32_t nfile, files[files_max]; + cbl_file_mode_t mode; + + cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e ) + : section(0), global(false), type(ec_none_e) + , nfile(0) + , mode(mode) + { + std::fill(files, files + COUNT_OF(files), 0); + } + cbl_declarative_t( ec_type_t type ) + : section(0), global(false), type(type) + , nfile(0) + , mode(file_mode_none_e) + { + std::fill(files, files + COUNT_OF(files), 0); + } + + cbl_declarative_t( size_t section, ec_type_t type, + const std::list& files, + cbl_file_mode_t mode, bool global = false ) + : section(section), global(global), type(type) + , nfile(files.size()) + , mode(mode) + { + assert( files.size() <= COUNT_OF(this->files) ); + std::fill(this->files, this->files + COUNT_OF(this->files), 0); + if( nfile > 0 ) { + std::copy( files.begin(), files.end(), this->files ); + } + } + cbl_declarative_t( const cbl_declarative_t& that ) + : section(that.section), global(that.global), type(that.type) + , nfile(that.nfile) + , mode(that.mode) + { + std::fill(files, files + COUNT_OF(files), 0); + if( nfile > 0 ) { + std::copy( that.files, that.files + nfile, this->files ); + } + } + + /* + * Sort file names before file modes, and file modes before non-IO. + */ + bool operator<( const cbl_declarative_t& that ) const { + // file name declaratives first, in section order + if( nfile != 0 ) { + if( that.nfile != 0 ) return section < that.section; + return true; + } + // file mode declaratives between file name declaratives and non-IO + if( mode != file_mode_none_e ) { + if( that.nfile != 0 ) return false; + if( that.mode == file_mode_none_e ) return true; + return section < that.section; + } + // all others by section, after names and modes + if( that.nfile != 0 ) return false; + if( that.mode != file_mode_none_e ) return false; + return section < that.section; + } + + // TRUE if there are no files to match, or the provided file is in the list. + bool match_file( size_t file ) const { + static const auto pend = files + nfile; + + return nfile == 0 || pend != std::find(files, files + nfile, file); + } + + // USE Format 1 names a file mode, or at least one file, and not an EC. + bool is_format_1() const { + assert(type != ec_none_e || nfile > 0 || mode != file_mode_none_e); + return nfile > 0 || mode != file_mode_none_e; + } +}; + + +/* + * ec_status_t represents the runtime exception condition status for + * any statement. Prior to execution, the generated code + * clears "type", and sets "source_file" and "lineno". + * + * If the statement includes some kind of ON ERROR + * clause, the generated code sets "handled" to the exception type + * handled by that clause, else it sets "handled" to ec_none_e. + * + * Post-execution, the generated code sets "type" to the appropriate + * exception, if any. The match-exception logic compares any raised + * exception to the set of declaratives, and returns a symbol-table + * index to the matching declarative, if any. + */ +class ec_status_t { + char msg[132]; +public: + ec_type_t type, handled; + cbl_name_t statement; // e.g., "ADD" + size_t lineno; + const char *source_file; + + ec_status_t() + : type(ec_none_e) + , handled(ec_none_e) + , lineno(0) + , source_file(NULL) + { + msg[0] = statement[0] = '\0'; + } + + ec_status_t& update(); + ec_status_t& enable( unsigned int mask ); + + const char * exception_location() { + snprintf(msg, sizeof(msg), "%s:%zu: '%s'", source_file, lineno, statement); + return msg; + } + ec_type_t unhandled() const { + return ec_type_t(static_cast(type) + & + ~static_cast(handled)); + } +}; + +#endif diff --git a/libgcobol/gcobolio.h b/libgcobol/gcobolio.h new file mode 100644 index 00000000000..061f24f309d --- /dev/null +++ b/libgcobol/gcobolio.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef GCOBOLIO_H_ +#define GCOBOLIO_H_ + +#include +#include +#include +#include + +typedef struct cblc_field_t + { + // This structure must match the code in structs.cc + unsigned char *data; // The runtime data. There is no null terminator + size_t capacity; // The size of "data" + size_t allocated; // The number of bytes available for capacity + size_t offset; // Offset from our ancestor (see note below) + char *name; // The null-terminated name of this variable + char *picture; // The null-terminated picture string. + char *initial; // The null_terminated initial value + struct cblc_field_t *parent;// This field's immediate parent field + size_t occurs_lower; // non-zero for a table + size_t occurs_upper; // non-zero for a table + size_t attr; // See cbl_field_attr_t + signed char type; // A one-byte copy of cbl_field_type_t + signed char level; // This variable's level in the naming heirarchy + signed char digits; // Digits specified in PIC string; e.g. 5 for 99v999 + signed char rdigits; // Digits to the right of the decimal point. 3 for 99v999 + int dummy; // GCC seems to want an even number of 32-bit values + } cblc_field_t; + +/* + * Implementation details + */ + +class supplemental_t; + +enum cblc_file_prior_op_t + { + file_op_none, + file_op_open, + file_op_start, + file_op_read, + file_op_write, + file_op_rewrite, + file_op_delete, + file_op_close, + }; + +/* end implementation details */ + +typedef struct cblc_file_t + { + // This structure must match the code in structs.cc + char *name; // This is the name of the structure; might be the name of an environment variable + char *filename; // The name of the file to be opened + FILE *file_pointer; // The FILE *pointer + cblc_field_t *default_record; // The record_area + size_t record_area_min; // The size of the smallest 01 record in the FD + size_t record_area_max; // The size of the largest 01 record in the FD + cblc_field_t **keys; // For relative and indexed files. The first is the primary key. Null-terminated. + int *key_numbers; // One per key -- each key has a number. This table is key_number + 1 + int *uniques; // One per key + cblc_field_t *password; // + cblc_field_t *status; // This must exist, and is the cbl_field_t version of io_status + cblc_field_t *user_status; // This might exist, and is another copy See 2014 standard, section 9.1.12 + cblc_field_t *vsam_status; // + cblc_field_t *record_length; // + supplemental_t *supplemental; // + void *implementation; // reserved for any implementation + size_t reserve; // From I-O section RESERVE clause + long prior_read_location; // Location of immediately preceding successful read + cbl_file_org_t org; // from ORGANIZATION clause + cbl_file_access_t access; // from ACCESS MODE clause + int mode_char; // 'r', 'w', '+', or 'a' from FILE OPEN statement + int errnum; // most recent errno; can't reuse "errno" as the name + file_status_t io_status; // See 2014 standard, section 9.1.12 + int padding; // Actually a char + int delimiter; // ends a record; defaults to '\n'. + int flags; // cblc_file_flags_t + int recent_char; // This is the most recent char sent to the file + int recent_key; + cblc_file_prior_op_t prior_op; // run-time type is INT + int dummy; + } cblc_file_t; + +#endif diff --git a/libgcobol/gfileio.cc b/libgcobol/gfileio.cc new file mode 100644 index 00000000000..9852dbf0f35 --- /dev/null +++ b/libgcobol/gfileio.cc @@ -0,0 +1,4660 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "io.h" +#include "common-defs.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "gfileio.h" +#include "charmaps.h" + +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wunused-result" + +/* Ordinary error-handling flow: + + file->errnum is always set to the value of the system ferror() function + file->io_status is always set to the COBOL specific value established + by the __gg__file_status_word function. + + When __gg__file_status_word is called with (FsErrno), it returns a value + based on the value of errno. Otherwise it returns the value it was called + with. + + So, after each operation, if we can figure out the COBOL response, we set + file->io_status t to that value. Otherwise, we set it to FsErrno and + let __gg__file_status_word establish the file->io_status_t value. + + */ + +/* Incomplete notes on file organization, written at the time I reworked + ORGANIZATION IS SEQUENTIAL + + GnucCOBOL: Defaults to ORGANIZATION IS SEQUENTIAL + GCOBOL: Defaults to ORGANIZATION IS LINE SEQUENTIAL + + SEQUENTIAL Where min/max record sizes are equal: + All records are output verbatim + SEQUENTIAL Where FD min/max record sizes are not the same + A 4-byte preamble is prepended to each record. + SEQUENTIAL Where FD record-clause is FORMAT 1 + [RECORD CONTAINS 10 CHARACTERS] + Just like sequential: The sizes of the FD records determine + whether or not preambles are issued. GnuCOBOL issues a warning + if an FD record size is greater than the record-clause size + SEQUENTIAL Where FD record-clause is FORMAT 2 [RECORD VARYING] + When all FD records are the same size: No preamble + When all FD records are different sizes: Preamble + SEQUENTIAL Where FD record-clause is FORMAT 2 [RECORD VARYING 70 TO 72] + When all FD records are the same size: No preamble + When all FD records are different sizes: Preamble + SEQUENTIAL Where FD record-clause is FORMAT 2 [RECORD VARYING DEPENDING ON] + There is always a preamble + SEQUENTIAL Where FD record-clause is FORMAT 3 + [RECORD CONTAINS I TO J CHARACTERS] + There is always a preamble + + */ + +extern "C" +void +__gg__handle_error(const char *function, const char *msg) + { + if(0) + { + fflush(stdout); + char ach[1024]; + snprintf(ach, sizeof(ach), "%s(): %s", function, msg); + perror(ach); + } + } + +static bool +handle_ferror(cblc_file_t *file, const char *function, const char *msg) + { + // This routine gets called after an operation that might result in a + // failure, or in an end-of-file + bool retval = false; // Indicates no error + file->errnum = ferror(file->file_pointer); + + // First, check for an end-of-file + if( file->file_pointer ) + { + if( feof(file->file_pointer) ) + { + // This is an end-of-file, which has its own COBOL status code, so it + // is error-ish: + retval = true; + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + } + else if( ferror(file->file_pointer) ) + { + // There was some kind of actionable error: + retval = true; + // Optionally tell the world of our troubles: + if(0) + { + fflush(stdout); + char ach[1024]; + snprintf(ach, sizeof(ach), "%s(): %s", function, msg); + perror(ach); + } + + // Set up for the next I/O operation by clearing out the error condition + clearerr(file->file_pointer); + } + } + else + { + // There is no file pointer. The most likely cause an attempt to open a + // file that doesn't exist. + fprintf(stderr, "%s(): called with NULL file->file_pointer\n", __func__); + abort(); + return true; + } + return retval; + } + +static bool +handle_errno(cblc_file_t *file, const char *function, const char *msg) + { + // This routine gets called after an operation that resulted in a + // errno failure + bool retval = false; // Indicates no error + file->errnum = errno; + + if( errno ) + { + // There was some kind of actionable error: + retval = true; + // Optionally tell the world of our troubles: + if(0) + { + fflush(stdout); + char ach[1024]; + snprintf(ach, sizeof(ach), "%s(): %s", function, msg); + perror(ach); + } + } + return retval; + } + +static +char * +get_filename( cblc_file_t *file, + int is_quoted) + { + static size_t fname_size = MINIMUM_ALLOCATION_SIZE; + static char *fname = (char *)malloc(MINIMUM_ALLOCATION_SIZE); + fname = internal_to_console(&fname, + &fname_size, + file->filename, + strlen(file->filename)); + + if( !is_quoted ) + { + // We have been given something that might be the name of an + // environment variable that contains the filename: + char *p_from_environment = getenv(fname); + if( p_from_environment ) + { + if( strlen(p_from_environment)+1 > fname_size ) + { + fname_size = strlen(p_from_environment)+1; + free(fname); + fname = (char *)malloc(fname_size); + } + strcpy(fname, p_from_environment); + } + } + + if(*fname) + { + // COBOL strings are space-filled to the right, so we have to get rid + // of any spaces out there. If somebody *wants* a filename space-filled + // to the right, well, at this juncture I am not prepared to be complicit + // in that particular flavor of lunacy. + size_t n = strlen(fname)-1; + // Note the conditional that terminates the loop when n goes from zero + // to a huge positive number in the event that the string is all SPACES + while( n < strlen(fname) && fname[n] == ascii_space ) + { + fname[n--] = '\0'; + } + } + return fname; + } + +static void +establish_status(cblc_file_t *file, long read_location) + { + // Call this routine with fs->errnum already set to errno. + // + // Establish file->io_status with either FsErrno or a specific value + // before calling this routine + + // Some operations have some state associated with them: + file->prior_read_location = read_location; + + // When this routine is called, file->io_status has been explicitly set to + // a COBOL status (in which case it will be left alone), or it is still + // at FsErrno, which means that errno will be used to translate to a COBOL + // status word. + file->io_status = __gg__file_status_word(file->io_status, file->errnum); + __gg__int128_to_field(file->status, + file->io_status, + 0, + truncation_e, + NULL); + // Set the EC-EXCEPTION accoring the status code + __gg__set_exception_file(file); + } + +extern "C" +void +__gg__set_user_status(cblc_field_t *ustatus, cblc_file_t *file) + { + __gg__int128_to_field(ustatus, + file->io_status, + 0, + truncation_e, + NULL); + } + +static long +max_value(cblc_field_t *key) + { + long retval; + if( key->digits ) + { + retval = (long)__gg__power_of_ten(key->digits)-1 ; + } + else + { + switch( key->capacity ) + { + case 1: + retval = 99; + break; + case 2: + retval = 9999; + break; + default: + retval = 999999999; + break; + } + } + return retval; + } + +extern "C" +void +__gg__file_init( + cblc_file_t *file, + const char *name, + cblc_field_t **keys, + int *key_numbers, + int *uniques, + cblc_field_t *default_record, + cblc_field_t *password, + cblc_field_t *user_status, + cblc_field_t *vsam_status, + cblc_field_t *record_length, + cblc_field_t *status, + size_t reserve, + int org, + int padding, + int access, + int optional, + size_t record_area_min, + size_t record_area_max) + { + if( !(file->flags & file_flag_initialized_e) ) + { + file->name = strdup(name); + file->filename = NULL ; + file->file_pointer = NULL ; + file->keys = keys; + file->key_numbers = key_numbers; + file->uniques = uniques; + file->default_record = default_record; + file->password = password ; + file->user_status = user_status ; + file->vsam_status = vsam_status ; + file->record_length = record_length ; + file->status = status ; + file->reserve = reserve ; + file->org = (cbl_file_org_t)org ; + file->padding = padding ; + file->access = (cbl_file_access_t)access ; + file->errnum = 0 ; + file->io_status = FsSuccess ; + file->delimiter = internal_newline ; + file->flags = 0; + file->flags |= (optional ? file_flag_optional_e : 0) + + file_flag_initialized_e; + file->record_area_min = record_area_min; + file->record_area_max = record_area_max; + file->prior_read_location = 0; + file->prior_op = file_op_none; + + if( file->access == file_inaccessible_e ) + { + file->access = file_access_seq_e; + } + } + } + +enum relative_file_mode + { + // MicroFocus uses a zero-byte prefix, and a two-byte postfix. The + // final byte is 0x0A for a valid record. + rfm_microfocus_e, + }; + +enum indexed_file_mode + { + // Data file is the same as rfm_microfocus. We use maps and multimaps for + // the keys, in an extravaganza of expedience. + ifm_dubner_e, + }; + +struct relative_file_parameters + { + long preamble_size; + long payload_size; + long postamble_size; + long record_size; + long file_size; + long key_value; + long record_position; + long flag_position; + long current_file_position; + int fd; + bool inside_existing_file; + }; + +#define IGNORE_LIMITS false +#define RESPECT_LIMITS true +#define DONT_INIT_KEY false +#define INIT_KEY true + +static bool +relative_file_parameters_get( struct relative_file_parameters &rfp, // OUTPUT + relative_file_mode rfm, // INPUTS + cblc_file_t *file, + bool respect_limits, + bool initialize_key, + bool is_random) + { + bool retval = false; // False means "okay" + switch(rfm) + { + // Note that the rfm is a nice idea, but at this point is not really being + // used. + case rfm_microfocus_e: + { + if( file->record_area_min == file->record_area_max ) + { + // Set MicroFocus-specific sizes: + rfp.preamble_size = 0; + rfp.payload_size = (long)file->record_area_max; + rfp.postamble_size = 2; + } + else + { + rfp.preamble_size = 8; + rfp.payload_size = (long)file->record_area_max; + rfp.postamble_size = 0; + } + rfp.record_size = rfp.preamble_size + + rfp.payload_size + + rfp.postamble_size; + + // We need to know the current file size: + errno = 0; + file->errnum = 0; + rfp.fd = fileno(file->file_pointer); + if( rfp.fd == -1 ) + { + file->io_status = FsErrno; + handle_errno(file, __func__, "fileno() error" ); + retval = true; + goto done; + } + + struct stat file_status; + errno = 0; + file->errnum = 0; + if( fstat(rfp.fd, &file_status) == -1 ) + { + file->io_status = FsErrno; + handle_errno(file, __func__, "fstat() error"); + retval = true; + goto done; + } + rfp.file_size = file_status.st_size; + + rfp.current_file_position = ftell(file->file_pointer); + if( handle_ferror(file, __func__, "ftell() error") ) + { + file->io_status = FsErrno; + retval = true; + goto done; + } + + if( !is_random ) + { + rfp.key_value = rfp.current_file_position/rfp.record_size + 1; + rfp.record_position = (rfp.key_value-1) * rfp.record_size; + rfp.inside_existing_file + = rfp.record_position + rfp.record_size <= rfp.file_size; + } + else + { + // Pick up the relative_key value: + if( initialize_key ) + { + rfp.key_value = rfp.current_file_position/rfp.record_size + 1; + } + else + { + int rdigits; + if( !file->keys[0] ) + { + warnx("%s(): %s file->keys[0] is NULL, and it shouldn't be\n", + __func__, + file->name); + if( !file->keys[0] ) + { + __gg__abort("relative_file_parameters_get(): file->keys is empty"); + } + } + rfp.key_value = (long)__gg__binary_value_from_field(&rdigits, + file->keys[0]); + } + + rfp.record_position = (rfp.key_value-1) * rfp.record_size; + if( rfp.record_position < 0 ) + { + // The record can't be found before the beginning of the file + file->io_status = FsNotFound; // "23" + retval = true; + goto done; + } + + rfp.inside_existing_file + = rfp.record_position + rfp.record_size <= rfp.file_size; + + if( respect_limits + && !rfp.inside_existing_file + && file->mode_char == 'r') + { + // This is a READ operation, but the targeted location is not inside + // the file + file->io_status = FsNotFound; // "23" + retval = true; + goto done; + } + } + + // For Microfocus, the flag is the final byte of the record: + rfp.flag_position = rfp.record_position + rfp.record_size - 1; + + break; + } + + default: + warnx("%s(): Unhandled relative_file_mode %d", __func__, rfm); + exit(1); + break; + } +done: + if( retval ) + { + establish_status(file, -1); + } + return retval; + } + +static void +relative_file_delete_varying(cblc_file_t *file, bool is_random) + { + file->errnum = 0; + file->io_status = FsErrno; + + size_t payload_length; + + unsigned char *stash = (unsigned char *)malloc(file->default_record->capacity); + memcpy(stash, file->default_record->data, file->default_record->capacity); + long starting_pos = ftell(file->file_pointer); + + if( !file->file_pointer ) + { + // Attempting to delete in a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( file->mode_char != '+' ) + { + // We have to be in I-O mode + file->io_status = FsNoDelete; // "49" + goto done; + } + + relative_file_parameters rfp; + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + RESPECT_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + if( !is_random ) + { + // Check that the prior operation was a successful read: + if( file->prior_read_location < 0) + { + file->io_status = FsNoRead; // "43" + goto done; + } + + // Turn that valid record into an empty one: + fseek(file->file_pointer, file->prior_read_location, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + payload_length = 0; + fwrite(&payload_length, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + else + { + // We are doing a random access: + + // Let's check to make sure the slot for this record is currently + // occupied: + + errno = 0; + file->errnum = 0; + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + fread(&payload_length, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + + if( !payload_length ) + { + // There isn't a record there for us to delete, which is an error + file->io_status = FsNotFound; // "23" + goto done; + } + + // Turn that valid record into an empty one: + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + payload_length = 0; + fwrite(&payload_length, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + +done: + memcpy(file->default_record->data, stash, file->default_record->capacity); + free(stash); + fseek(file->file_pointer, starting_pos, SEEK_SET); + + establish_status(file, -1); + } + +static void +relative_file_delete(cblc_file_t *file, bool is_random) + { + if( file->record_area_min != file->record_area_max ) + { + return relative_file_delete_varying(file, is_random); + } + + file->errnum = 0; + file->io_status = FsErrno; + + char record_marker; + + unsigned char *stash = (unsigned char *)malloc(file->default_record->capacity); + memcpy(stash, file->default_record->data, file->default_record->capacity); + + long starting_pos = ftell(file->file_pointer); + + if( !file->file_pointer ) + { + // Attempting to delete in a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( file->mode_char != '+' ) + { + // We have to be in I-O mode + file->io_status = FsNoDelete; // "49" + goto done; + } + + relative_file_parameters rfp; + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + RESPECT_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + if( !is_random ) + { + // Check that the prior operation was a successful read: + if( file->prior_read_location < 0) + { + file->io_status = FsNoRead; // "43" + goto done; + } + + // Turn that valid record into an empty one: + record_marker = 0x00; + errno = 0; + file->errnum = 0; + if( pwrite( rfp.fd, + &record_marker, + 1, + file->prior_read_location + + rfp.record_size - 1 ) == -1 ) + { + handle_errno(file, __func__, "pwrite() error"); + goto done; + } + } + else + { + // We are doing a random access: + + // Let's check to make sure the slot for this record is currently + // occupied: + + errno = 0; + file->errnum = 0; + ssize_t presult = pread(rfp.fd, &record_marker, 1, rfp.flag_position); + if( presult < 0 ) + { + handle_errno(file, __func__, "pread() error"); + goto done; + } + + if( presult == 0 || record_marker != internal_newline ) + { + // There isn't a record there for us to delete, which is an error + file->io_status = FsNotFound; // "23" + goto done; + } + + // We now clobber the 0x0A record marker: + record_marker = 0x00; + errno = 0; + file->errnum = 0; + if( pwrite(rfp.fd, &record_marker, 1, rfp.flag_position) == -1 ) + { + file->errnum = errno; + handle_ferror(file, __func__, "pwrite() error"); + goto done; + } + } + +done: + memcpy(file->default_record->data, stash, file->default_record->capacity); + free(stash); + fseek(file->file_pointer, starting_pos, SEEK_SET); + establish_status(file, -1); + } + +static std::vector +file_indexed_make_key(cblc_file_t *file, int key_number) + { + std::vector retval; + int index = 0; + while( file->key_numbers[index] != -1 ) // -1 is the guardrail + { + if( file->key_numbers[index] == key_number ) + { + unsigned char *location = file->keys[index]->data; + for(size_t i=0; ikeys[index]->capacity; i++ ) + { + retval.push_back(*location++); + } + } + index += 1; + } + return retval; + } + +static long +file_indexed_first_position(cblc_file_t *file, int key_number) + { + // We need to find the file position for the given key: + long retval = -1; + + // Pick up our structure for this key_number + file_index_t *file_index = &file->supplemental->indexes[key_number]; + + // Build the key value for the given key_number + std::vector key = file_indexed_make_key(file, key_number); + + // Find the pair of pointers to the first and last matches + std::pair < std::multimap, long>::iterator, + std::multimap, long>::iterator> ret; + ret = file_index->key_to_position.equal_range(key); + file_index->current_iterator = ret.first; + file_index->ending_iterator = ret.second; + + if( ret.first != ret.second ) + { + // There is one or more entries that match the key. We are returning + // the location from the first. We leave "recent_indicator" as the one + // we found. + retval = ret.first->second; + } + return retval; + } + +static int +read_an_indexed_record( cblc_file_t *file, + long max_bytes, + long &record_length, + int &flag) + { + int retval = 2; // zero is okay; 1 is EOF, 2 is an ERROR + size_t bytes_read; + size_t bytes_to_read; + + // Call this routine with the file positioned at the record to read + + // We need to read in the four-byte preamble plus record_area_min bytes + // of the record to be deleted. We need those bytes in order to calculate + // all of the keys of indexes that might have to be removed: + + unsigned char ach[4]; + bytes_read = fread(ach, 1, 4, file->file_pointer); + file->errnum = ferror(file->file_pointer); + if( feof(file->file_pointer) || bytes_read < 4 ) + { + clearerr(file->file_pointer); + retval = 1; // Flag the EOF + goto done; + } + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + + record_length = ach[0]<<8; + record_length += ach[1]; + if(ach[2] != 0) + { + warnx("Bad file format in read_an_indexed_record(). " + "Third byte should be zero"); + abort(); + } + + flag = ach[3]; + + bytes_to_read = record_length; + if( record_length > max_bytes ) + { + // The record length in the file is too big for us to read into our + // record area. + + // Read as many bytes as we can: + bytes_to_read = max_bytes; + } + + file->errnum = 0; + bytes_read = fread(file->default_record->data, + 1, + bytes_to_read, + file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + if( bytes_read != bytes_to_read) + { + // Weird. We couldn't read a minimal number of bytes + goto done; + } + + if( record_length > max_bytes ) + { + // The record length in the file was too big. So, we read what we could. + // Now we need to adjust the file pointer to skip past the bytes we weren't + // able to read: + fseek(file->file_pointer, record_length - max_bytes, SEEK_CUR); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + retval = 0; // Indicate that all is well + done: + return retval; + } + +struct position_state_t + { + int recent_key; + long starting_position; + std::vector, long>::iterator> currents; + std::vector, long>::iterator> endings; + }; + +static void +position_state_preserve(cblc_file_t *file, position_state_t &state) + { + state.recent_key = file->recent_key; + state.starting_position = ftell(file->file_pointer); + if( handle_ferror(file, __func__, "ftell() error") ) + { + exit(1); + } + for(size_t i=1; isupplemental->indexes.size(); i++) + { + state.currents.push_back(file->supplemental->indexes[i].current_iterator); + state.endings.push_back (file->supplemental->indexes[i].ending_iterator ); + } + } + +static void +position_state_restore(cblc_file_t *file, position_state_t &state) + { + file->recent_key = state.recent_key; + fseek(file->file_pointer, state.starting_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + exit(1); + } + for(size_t i=1; isupplemental->indexes.size(); i++) + { + // Remember that key numbers range from 1 to N, whilst the vector we + // we created to stash the iterators started at zero. + file->supplemental->indexes[i].current_iterator = state.currents[i-1]; + file->supplemental->indexes[i].ending_iterator = state.endings[i-1]; + } + } + +static void +indexed_file_delete(cblc_file_t *file, bool is_random) + { + file->errnum = 0; + file->io_status = FsErrno; + + long fpos; + unsigned char *stash = NULL; + long record_length; + int flag; + file_hole_t new_hole; + position_state_t position_state; + + if( !file->file_pointer ) + { + // Attempting to delete in a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( file->mode_char != '+' ) + { + // We have to be in I-O mode + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( !is_random && file->prior_read_location == -1 ) + { + // When the access mode is sequential, the prior operation shall have been a + // successful read statement. It is that record which is removed. Not + // meeting that requirement gets its own error code: + file->io_status = FsNoRead; // "43" + goto done; + } + + // For both sequential and random access, we need to read the record to be + // deleted into the record area. It could be I am being overly didactic, but + // my reading of the ISO spec indicates that there has to be a successful read + // of the record in sequential mode, but I don't see a requirement that the] + // programmer leave the record area untouched before trying to delete it. + + // Likewise, for random access, the primary key has to be valid, but I see + // no requirement that the alternate keys be valid. We need the alternate + // keys in place in order to delete them from the indexes. + + // The requirements for a delete are that both the file position indicator + // and the record area itself are unchanged by the delete operation. + + // So, we save the current record area: + stash = (unsigned char *)malloc(file->record_area_max); + memcpy(stash, file->default_record->data, file->record_area_max); + + // And the position state of our file + position_state_preserve(file, position_state); + + if( !is_random ) + { + // For sequential, re-read the recent successful read: + fpos = file->prior_read_location; + } + else + { + // We are doing a random read. Figure out the position from the primary + // key: + fpos = file_indexed_first_position(file, 1); + if( fpos == -1 ) + { + // The primary key does not exist + file->io_status = FsNotFound; // "23" + goto done; + } + } + + // Read the record to be deleted into the record area: + fseek(file->file_pointer, fpos, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + if( read_an_indexed_record( file, + file->record_area_max, + record_length, + flag) ) + { + goto done; + } + + // The record we just read *has* to be a good record: + if( flag != 1 ) + { + warnx("Bad file format in indexed_file_delete(). " + "Fourth byte should be one"); + abort(); + } + + // Because we are deleting it, we need to remove it from all of the indexes. + // Given our indexes, we need to scan all of them looking for the matching + // fpos value. And then we have to start over again, because the deletion + // changes the tree that implements the multimap. If speed becomes an issue, + // a bandaid fix would be to create a multi-map of fpos to iterator. + + // The real fix is a real database, but somewhere before that we need to + // really design an indexed file system, instead of this business of putting + // it on a stick an banging a few nails through it. + + for(size_t key_number=1; + key_numbersupplemental->indexes.size(); + key_number++) + { + file_index_t *file_index = &file->supplemental->indexes[key_number]; + if( file->supplemental->uniques[key_number] ) + { + // This key does not allow duplicates, so we don't have to scan for it, + // because we know we have to delete it. + file_indexed_first_position(file, key_number); + file_index->key_to_position.erase(file_index->current_iterator); + // and continue to the next key number + continue; + } + else + { + // This particular key allows duplicates + + // We have to scan the entire index for keys that point to our fpos. When + // we find one, we check to see if the keys match. If the keys don't + // match, then we have to remove the existing one from the index. + + std::vector the_key + = file_indexed_make_key(file, key_number); + bool deleting = true; + while(deleting) + { + deleting = false; + std::multimap, long>::iterator it + = file_index->key_to_position.begin(); + while( it != file_index->key_to_position.end() ) + { + if( it->second == fpos ) + { + // We have found an index that points to our record. + // It needs to be deleted. + file_index->key_to_position.erase(it); + deleting = true; + break; + } + it++; + } + } + } + } + + // We need to turn this record into a hole by changing the fourth byte from + // one to zero + + fseek(file->file_pointer, fpos+3, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + fputc(0, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error") ) + { + goto done; + } + + // We just created a hole; put it in the list: + new_hole.location = fpos; + new_hole.size = record_length; + file->supplemental->holes.push_back(new_hole); + +done: + if( stash ) + { + // Restore the stashed record area: + memcpy(file->default_record->data, stash, file->record_area_min); + free(stash); + stash = NULL; + position_state_restore(file, position_state); + } + + establish_status(file, -1); + } + +static void +__io__file_delete(cblc_file_t *file, bool is_random) + { + switch(file->org) + { + case file_relative_e: + relative_file_delete(file, is_random); + break; + + case file_indexed_e: + indexed_file_delete(file, is_random); + break; + + default: + warnx("%s(): Unhandled file organization", __func__); + exit(1); + break; + } + + if( file->io_status < FhNotOkay ) + { + file->flags |= file_flag_existed_e; + } + file->prior_op = file_op_delete; + } + +static void +indexed_file_start( cblc_file_t *file, + int relop, + int key_number, + size_t length) + { + static const int first_key = 1; + //fprintf(stderr, " length is %ld\n", length); + file->io_status = FsNotFound; // "23" + + size_t length_of_key = 0; + bool direction_reverse; + std::multimap, long>::iterator it; + file_index_t *file_index; + std::vector the_key; + + if( key_number == -1 ) + { + // This is FIRST: + file_index = &file->supplemental->indexes[first_key]; + if( file_index->key_to_position.size() ) + { + it = file_index->key_to_position.begin(); + file->io_status = FsErrno; + key_number = first_key; + } + goto done; + } + if( key_number == -2 ) + { + // This is LAST: + file_index = &file->supplemental->indexes[first_key]; + if( file_index->key_to_position.size() ) + { + it = file_index->key_to_position.end(); + it--; + file->io_status = FsErrno; + key_number = first_key; + } + goto done; + } + + // Pick up our file index for this key number + file_index = &file->supplemental->indexes[key_number]; + + // We are going to need the key from the existing record: + the_key = file_indexed_make_key(file, key_number); + length_of_key = the_key.size(); + + // Make sure the length parameter is within the size of the actual key + if( length < 1 || length > length_of_key ) + { + file->io_status = FsNotFound; // "23" + goto done; + } + + direction_reverse = (relop==lt_op || relop==le_op); + + if( direction_reverse ) + { + // We will do a forward search for the biggest index that is smaller than + // the key. + std::multimap, long>::iterator bestie = + file_index->key_to_position.end(); + it = file_index->key_to_position.begin(); + while( it != file_index->key_to_position.end() ) + { + const unsigned char *the_index = it->first.data(); + + // Do the comparison: + int result = 0; + + for(size_t i=0; i 0 ) + { + // The index is bigger than the key, so, for better or for worse, we + // are done looking. + break; + } + + if( result == 0 ) + { + // The index and key are equal + if( relop == le_op ) + { + // We have equal, and we were looking for equality. Set a conditional + // winner, and then keep looking in case there are more indexes that + // are equal to the key + bestie = it; + file->io_status = FsErrno; + } + } + else if( result < 0 ) + { + // The index is less than the key. + if( relop == lt_op + || relop == le_op ) + { + // This is a conditional winner, so we flag it as such and keep going, + // because there might be more indexes that are bigger than this one + // but less than the key + bestie = it; + file->io_status = FsErrno; + } + } + // At this point, the index is less than the key, so we keep looking: + it++; + } + if( file->io_status == FsErrno ) + { + // We found something + it = bestie; + } + } + else + { + // We are doing a forward search for the first index entry that matches + // the criterion. + + it = file_index->key_to_position.begin(); + while( it != file_index->key_to_position.end() ) + { + const unsigned char *the_index = it->first.data(); + + // Do the comparison: + int result = 0; + + for(size_t i=0; iio_status = FsErrno; + goto done; + } + else + { + // The operation is gt_op, so we fall through and keep looking + } + } + else if( result > 0 ) + { + // The the index is bigger than the key + if( relop == eq_op ) + { + // The index is bigger than the key, so we will never find + // equality. + goto done; + } + // At the point, the operation has to be ge_op or gt_op, so our + // criterion is satisfied + file->io_status = FsErrno; + goto done; + } + // At this point, the index is less than the key, so we keep looking: + it++; + } + // We went through the whole index without finding anything. + } +done: + if( file->io_status == FsErrno ) + { + // The it iterator points to a valid found index: + file_index->current_iterator = it; + file_index->ending_iterator = file_index->key_to_position.end(); + + fseek(file->file_pointer, it->second, SEEK_SET); + handle_ferror(file, __func__, "fseek() error"); + + file->recent_key = key_number; + } + } + +static long +relative_file_start(cblc_file_t *file, + int first_last_key, + int relop) + { + long fpos = -1; + relative_file_parameters rfp; + int rdigits; + long total_record_length; + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + IGNORE_LIMITS, + INIT_KEY, + true) ) + { + goto done; + } + total_record_length + = rfp.preamble_size + rfp.payload_size + rfp.postamble_size; + if( first_last_key == -1 ) + { + // This is FIRST. Search forward from the beginning + rfp.key_value = 1; + relop = ge_op; + } + else if( first_last_key == -2 ) + { + // This is LAST. Search reverse from the end + rfp.key_value = rfp.file_size / total_record_length; + relop = le_op; + } + else + { + rfp.key_value = (long)__gg__binary_value_from_field(&rdigits, + file->keys[0]); + } + + bool forward; + switch( relop ) + { + case eq_op: + case ge_op: + forward = true; + break; + case le_op: + forward = false; + break; + case gt_op: + rfp.key_value += 1; + forward = true; + break; + case lt_op: + rfp.key_value -= 1; + forward = false; + break; + default: + warnx("%s(): relop is %d, which we don't know how to handle", + __func__, + relop); + exit(1); + break; + } + + if( forward ) + { + // We are searching forward, so we want the key_value to be 1 or more + rfp.key_value = std::max( rfp.key_value, (long)1); + } + else + { + // We are searching backward, so we want the rfp.key_value to be at most + // the last possible record based on the file size: + rfp.key_value = std::min( rfp.key_value, + rfp.file_size / total_record_length); + } + + // Let's initialize for searching for a valid record: + rfp.record_position = (rfp.key_value-1) * total_record_length; + rfp.flag_position = rfp.record_position + rfp.record_size - 1; + + // And let the searching begin: + + while( rfp.record_position >= 0 + && rfp.record_position+total_record_length <= rfp.file_size ) + { + char record_marker; + ssize_t presult = pread(rfp.fd, &record_marker, 1, rfp.flag_position); + if( presult < 0 ) + { + handle_errno(file, __func__, "pread() error"); + goto done; + } + if( presult == 0 ) + { + // end of file + goto done; + } + if( record_marker == internal_newline ) + { + // The record is a valid one + fpos = rfp.record_position; + goto done; + } + // That position in the file did not have valid data in it. Move on to the + // next record + if( forward ) + { + rfp.key_value += 1; + rfp.record_position += total_record_length; + rfp.flag_position += total_record_length; + } + else + { + rfp.key_value -= 1; + rfp.record_position -= total_record_length; + rfp.flag_position -= total_record_length; + } + } + + if( fpos == -1) + { + // We didn't find a valid record + file->io_status = FsNotFound; // "23" + goto done; + } + + // Position the file at the requested record: + done: + if( fpos >= 0) + { + fseek(file->file_pointer, fpos, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + // It's unclear to me whether or not START is supposed to update keys like + // this + // Update the key with the one we found + // __gg__int128_to_field(file->keys[0], + // rfp.key_value, + // 0, + // truncation_e, + // NULL); + } + + return fpos; + } + + +static void +__io__file_start( cblc_file_t *file, + int relop, + int first_last_key, + size_t length) + { + // According to IBM Language Reference 6.3, whether or not 'key' is specified, + // the value used is from the RELATIVE KEY clause. See page 421 "Relative + // Files" "Whether or not the KEY phrase is specified, the key data item used + // in the comparison is the RELATIVE KEY data item." + file->errnum = 0; + file->io_status = FsErrno; + long fpos = -1; + + bool okay; + + if( !file->file_pointer ) + { + // Attempting to START a file that isn't open + if( file->flags & file_flag_optional_e ) + { + file->io_status = FsNotFound; // "23" + } + else + { + file->io_status = FsReadNotOpen; // "47" + } + goto done; + } + + okay = (file->org == file_indexed_e || file->org == file_relative_e) + && ( file->access == file_access_seq_e + || file->access == file_access_dyn_e) + && (file->mode_char == 'r' || file->mode_char == '+') ; + if( !okay ) + { + file->io_status = FsReadNotOpen; // "47" + goto done; + } + + if( file->org == file_relative_e ) + { + fpos = relative_file_start(file, first_last_key, relop); + } + else + { + // first_last_key is the key_number + indexed_file_start(file, relop, first_last_key, length); + if( file->io_status == FsErrno ) + { + fpos = 0; + } + } + +done: + if( file->io_status == FsErrno ) + { + file->flags |= file_flag_existed_e; + } + + establish_status(file, fpos); + if( file->io_status < FhNotOkay ) + { + file->flags |= file_flag_existed_e; + } + file->prior_op = file_op_start; + } + +static void +sequential_file_rewrite( cblc_file_t *file, size_t length ) + { + // Handles sequential files + + file->errnum = 0; + file->io_status = FsErrno; + + long starting_position = -1; + bool okay; + size_t bytes_to_write; + + if( !file->file_pointer ) + { + // Attempting to read a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + okay = (file->mode_char == '+'); + + if( !okay ) + { + file->io_status = FsNoDelete; // "49" + goto done; + } + + starting_position = ftell(file->file_pointer); + // Check for EOF before calling ferror, which clears feof + if( feof( file->file_pointer) ) + { + // Trying to do a rewrite at the end-of-file position has its own code: + file->io_status = FsNoRead; // "43" + goto done; + } + if( handle_ferror(file, __func__, "ftell() error") ) + { + goto done; + } + + if( file->prior_read_location == -1 ) + { + // The prior operation was not a successful read: + file->io_status = FsNoRead; // "43" + goto done; + } + + fseek(file->file_pointer, file->prior_read_location, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + size_t existing_size; + if( file->record_area_min != file->record_area_max ) + { + // Because of the different sizes, we are expecting a preamble: + + // An error at this point is either an error, or a true end-of-file. + unsigned char preamble[4]; + size_t characters_read = fread(preamble, 1, 4, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + // This also comes back true for an ordinary end-of-file + goto done; + } + + if( characters_read != 4 ) + { + // If the preamble is incomplete, treat that as an EOF + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + + // Extract the count of bytes in the record from the preamble + existing_size = ((size_t)preamble[0]<<8) + preamble[1]; + } + else + { + // Because the min and max are the same, we figure on writing that many + // characters: + existing_size = file->record_area_max; + } + + // We need to make sure that the number of bytes we've been asked + // to write is valid: + + // By default, we write what we've been asked to write. + bytes_to_write = length; + + // But that can be overridden by a depending_on from the + // FILE-CONTROL paragraph: + + if( file->record_length ) + { + int rdigits; + bytes_to_write = (size_t)__gg__binary_value_from_field( + &rdigits, + file->record_length); + } + + if( bytes_to_write < file->record_area_min + || bytes_to_write > file->record_area_max + || bytes_to_write != existing_size ) + { + file->io_status = FsBoundWrite; // "44" + goto done; + } + + if( file->record_area_min != file->record_area_max ) + { + unsigned char preamble[4] = + { + (unsigned char)(bytes_to_write>>8), + (unsigned char)(bytes_to_write), + 0, + 0 + }; + + fwrite( preamble, + 4, + 1, + file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + + fwrite( file->default_record->data, + bytes_to_write, + 1, + file->file_pointer ); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + +done: + // Per the standard, return the file location pointer back to whence it came: + fseek(file->file_pointer, starting_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + establish_status(file, starting_position); + } + +static void +relative_file_rewrite_varying( cblc_file_t *file, bool is_random ) + { + file->errnum = 0; + file->io_status = FsErrno; + + long starting_position = -1; + relative_file_parameters rfp; + size_t payload_size; + + if( !file->file_pointer ) + { + // Attempting to rewrite a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( file->mode_char != '+' ) + { + file->io_status = FsNoDelete; // "49" + goto done; + } + + starting_position = ftell(file->file_pointer); + // Check for EOF before calling ferror, which clears feof + if( feof( file->file_pointer) ) + { + // Trying to do a rewrite at the end-of-file position has its own code: + file->io_status = FsNoRead; // "43" + goto done; + } + if( handle_ferror(file, __func__, "ftell() error") ) + { + goto done; + } + + if( !is_random ) + { + // The access mode is sequential, so we can leverage + // sequential_file_rewrite + rfp.record_position = starting_position; + goto do_the_write; + } + else + { + // This is like a write, except the place we are putting + // it has to be occupied instead of empty. + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + RESPECT_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + do_the_write: + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + fread(&payload_size, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + + if( !payload_size ) + { + // The record is not empty: + file->io_status = FsNotFound; // "23" + goto done; + } + + payload_size = file->default_record->capacity; + if( payload_size < file->record_area_min + || payload_size > file->record_area_max) + { + file->io_status = FsBoundWrite; // "44" + goto done; + } + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + // We can overwrite the valid record: + fwrite( &payload_size, + 8, + 1, + file->file_pointer ); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + fwrite( file->default_record->data, + file->default_record->capacity, + 1, + file->file_pointer ); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + +done: + // Per the standard, return the file location pointer back to whence it came: + fseek(file->file_pointer, starting_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + establish_status(file, starting_position); + } + +static void +relative_file_rewrite( cblc_file_t *file, size_t length, bool is_random ) + { + if( file->record_area_min != file->record_area_max ) + { + return relative_file_rewrite_varying(file, is_random); + } + + file->errnum = 0; + file->io_status = FsErrno; + + long starting_position = -1; + relative_file_parameters rfp; + + if( !file->file_pointer ) + { + // Attempting to rewrite a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( file->mode_char != '+' ) + { + file->io_status = FsNoDelete; // "49" + goto done; + } + + starting_position = ftell(file->file_pointer); + // Check for EOF before calling ferror, which clears feof + if( feof( file->file_pointer) ) + { + // Trying to do a rewrite at the end-of-file position has its own code: + file->io_status = FsNoRead; // "43" + goto done; + } + if( handle_ferror(file, __func__, "ftell() error") ) + { + goto done; + } + + if(!is_random) + { + // The access mode is sequential, so we can leverage + // sequential_file_rewrite + sequential_file_rewrite(file, length); + goto done; + } + else + { + // This is like a write, except the place we are putting + // it has to be occupied instead of empty. + char record_marker; + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + RESPECT_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + ssize_t presult = pread(rfp.fd, &record_marker, 1, rfp.flag_position); + if( presult < 0 ) + { + handle_errno(file, __func__, "pread() error"); + goto done; + } + + if( presult == 0 || record_marker != internal_newline ) + { + // The record is not specified: + file->io_status = FsNotFound; // "23" + goto done; + } + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + // We can overwrite the valid record: + fwrite( file->default_record->data, + file->default_record->capacity, + 1, + file->file_pointer ); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + +done: + // Per the standard, return the file location pointer back to whence it came: + fseek(file->file_pointer, starting_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + establish_status(file, starting_position); + } + +static bool +file_indexed_update_indices(cblc_file_t *file, + long record_position, + bool dupes_okay = false) + { + // We have a record in the file->record_area. + + bool okay = true; + + // We have to do this in two passes. + + // First, we check to see that for all keys flagged as unique, that + // the key doesn't already exist: + + for(size_t key_number=1; + key_numbersupplemental->indexes.size(); + key_number++) + { + if( file->supplemental->uniques[key_number] ) + { + // This key has to be unique: + std::vectorkey_value = + file_indexed_make_key(file, key_number); + file_index_t *file_index = &file->supplemental->indexes[key_number]; + std::multimap, long>::const_iterator it = + file_index->key_to_position.find(key_value); + if( it != file_index->key_to_position.end() ) + { + // This key is already in the index + if( !dupes_okay || it->second != record_position ) + { + // We have a key violation: + file->io_status = FsDupWrite; // "22" + okay = false; + break; + } + } + } + } + + if( okay ) + { + // There were no key violations, so we can do the second pass, which inserts + // the keys into the indexes. + for(size_t key_number=1; + key_numbersupplemental->indexes.size(); + key_number++) + { + file_index_t *file_index = &file->supplemental->indexes[key_number]; + // But we don't want the key to end up in here twice, which we have to + // avoid when updating the indexes after a REWRITE + + bool safe_to_insert = true; + file_indexed_first_position(file, key_number); + while( file_index->current_iterator != file_index->ending_iterator ) + { + if( file_index->current_iterator->second == record_position) + { + safe_to_insert = false; + break; + } + file_index->current_iterator++; + } + + if( safe_to_insert ) + { + std::vectorkey_value = + file_indexed_make_key(file, key_number); + std::pair, long> + to_insert(key_value, record_position); + file_index->key_to_position.insert(to_insert); + } + } + } + return okay; + } + +static void +indexed_file_rewrite( cblc_file_t *file, size_t /*length*/, bool is_random ) + { + file->errnum = 0; + file->io_status = FsErrno; + + long fpos = -1; + position_state_t position_state; + long record_length; + + if( !file->file_pointer ) + { + // Attempting to work on a file that isn't open + file->io_status = FsNoDelete; // "49" + goto done; + } + + if( file->mode_char != '+' ) + { + // For an indexed_file REWRITE, the mode has to be '+' + file->io_status = FsNoDelete; // "49" + goto done; + } + + // We need to preserve the file position state + position_state_preserve(file, position_state); + + if( !is_random ) + { + // In the case of sequential access, the prior operation needed to be a + // successful read: + if( file->prior_read_location == -1 ) + { + // The prior operation was not a successful read: + file->io_status = FsNoRead; // "43" + goto done; + } + + // The prior read was successful. Let's see if the primary key has changed + fpos = file_indexed_first_position(file, 1); + if( fpos != file->prior_read_location ) + { + // Between the successful read and this attempt at a rewrite, somebody + // changed the primary key in the record. This gets its own special error + // code + file->io_status = FsKeySeq; // "21" + goto done; + } + } + else + { + // It's not a sequential read, so it's got to be random. Let's determine + // that the primary key is valid: + fpos = file_indexed_first_position(file, 1); + if( fpos == -1 ) + { + file->io_status = FsNotFound; // "23" + goto done; + } + } + + // We need to know the record length: + fseek(file->file_pointer, fpos, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + fpos = -1; + goto done; + } + + unsigned char preamble[4]; + fread(preamble, 1, 4, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + fpos = -1; + goto done; + } + record_length = (preamble[0]<<8) + preamble[1]; + // Note that after the read, the file position is at the beginning of the + // record. + + // We know we have a good primary key. It points to fpos. + + // We now need to check any alternate keys flagged as unique. We need to + // make sure that any such key this record has already points to fpos. + + // If it points somewhere else, then our attempt to rewrite the record would + // end up that key pointing to two different records, which means a failure: + + for(size_t key_number=2; + key_numbersupplemental->indexes.size(); + key_number++) + { + if( file->supplemental->uniques[key_number] ) + { + // This particular alternative index does not allow duplicates + long altfpos = file_indexed_first_position(file, key_number); + if( altfpos != -1 && altfpos != fpos ) + { + // This alternate key would create a duplicate index entry where none + // such are allowed: + file->io_status = FsDupWrite; // "22" + goto done; + } + } + } + + // At this point we know we are going to write the record, because there will + // be no key violations. But because an alternate key might have changed, we + // we have to scan for all such and remove them from the indexes: + for(size_t key_number=2; + key_numbersupplemental->indexes.size(); + key_number++) + { + if( !file->supplemental->uniques[key_number] ) + { + // This particular alternative index allows duplicates + file_index_t *file_index = &file->supplemental->indexes[key_number]; + + // We have to scan the entire index for keys that point to our fpos. When + // we find one, we check to see if the keys match. If the keys don't + // match, then we have to remove the existing one from the index. + + std::vector the_key + = file_indexed_make_key(file, key_number); + bool deleting = true; + while(deleting) + { + deleting = false; + std::multimap, long>::iterator it + = file_index->key_to_position.begin(); + while( it != file_index->key_to_position.end() ) + { + if( it->second == fpos ) + { + // We have found an index entry that points to our record. If the + // index's key doesn't match our calculated key, we need to delete + // it. + const unsigned char *the_index = it->first.data(); + int result = 0; + for(size_t i=0; ikey_to_position.erase(it); + deleting = true; + break; + } + } + it++; + } + } + } + } + + // To recap: The primary key is valid, and any remaining alternative keys + // are already pointing to fpos, and if a new one gets entered, it won't + // conflict with any existing key flagged as unique. + + // We can now write the data out, at the given location: + + fwrite( file->default_record->data, + 1, + record_length, + file->file_pointer ); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + // And it is safe to update the keys: + file_indexed_update_indices(file, + fpos, + true); // Set to true to indicate that might + // // occur and should be ignored + +done: + // Per the standard, return thefile location pointer back to whence it came: + if( fpos != -1 ) + { + position_state_restore(file, position_state); + } + + establish_status(file, fpos); + file->prior_read_location = -1; + } + +static void +__io__file_rewrite(cblc_file_t *file, size_t length, bool is_random) + { + switch(file->org) + { + case file_relative_e: + relative_file_rewrite(file, length, is_random); + break; + + case file_sequential_e: + sequential_file_rewrite(file, length); + break; + + case file_indexed_e: + indexed_file_rewrite(file, length, is_random); + break; + + default: + warnx("%s(): Unhandled file organization", __func__); + exit(1); + break; + } + if( file->io_status < FhNotOkay ) + { + file->flags |= file_flag_existed_e; + } + file->prior_op = file_op_rewrite; + } + +static void +relative_file_write_varying(cblc_file_t *file, + unsigned char *location, + size_t length, + bool is_random) + { + // This routine handles variable-length writes to RELATIVE files + file->errnum = 0; + file->io_status = FsErrno; + + long necessary_file_size; + size_t payload_length; + + relative_file_parameters rfp; + + if( is_random ) + { + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + IGNORE_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + // If the file isn't big enough, we need to expand it: + necessary_file_size = rfp.record_position + + rfp.record_size; + if( rfp.file_size < necessary_file_size ) + { + // Position the file position indicator to the very end of the file + fseek(file->file_pointer, 0, SEEK_END); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + // Expand the file to the necessary length: + while( rfp.file_size++ < necessary_file_size-1 ) + { + fputc(0, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error [2]") ) + { + goto done; + } + } + } + + // Position the file pointer at the slot: + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + fread(&payload_length, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + + if( payload_length != 0 ) + { + // The slot has something in it already: + file->io_status = FsDupWrite; // "22" + goto done; + } + + // Position the file pointer at the slot: + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + else + { + // We need to do a sequential write: + if( file->mode_char == 'a' ) + { + // Position the file pointer at the end: + fseek(file->file_pointer, 0, SEEK_END); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + } + + // Write out the record. + // We need a length. + + if( file->record_length ) + { + // df + int rdigits; + length = (size_t)__gg__binary_value_from_field( &rdigits, + file->record_length); + } + + payload_length = length; + + if( payload_length < file->record_area_min + || payload_length > file->record_area_max) + { + file->io_status = FsBoundWrite; // "44" + goto done; + } + + fwrite(&payload_length, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + fwrite(location, 1, payload_length, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + while( payload_length < file->record_area_max ) + { + fputc(internal_space, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error") ) + { + goto done; + } + payload_length += 1; + } + + if( is_random ) + { + // Per the COBOL specification, put the file position back to where + // it was when we started this exercise: + fseek(file->file_pointer, rfp.current_file_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek(starting_pos) error") ) + { + goto done; + } + } + +done: + establish_status(file, -1); + } + +static void +relative_file_write(cblc_file_t *file, + unsigned char *location, + size_t length, + bool is_random) + { + // This routine handles writes to RELATIVE files + + if( file->record_area_min != file->record_area_max ) + { + return relative_file_write_varying(file, location, length, is_random); + } + + file->errnum = 0; + file->io_status = FsErrno; + + long necessary_file_size; + unsigned char achPostamble[] = {internal_cr, internal_newline}; + + relative_file_parameters rfp; + + if( is_random ) + { + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + IGNORE_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + necessary_file_size = rfp.record_position + + rfp.preamble_size + + rfp.payload_size + + rfp.postamble_size; + if( rfp.file_size < necessary_file_size ) + { + // Position the file position indicator to the very end of the file + fseek(file->file_pointer, 0, SEEK_END); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + + // Expand the file to the necessary length: + while( rfp.file_size++ < necessary_file_size-1 ) + { + fputc(0, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error [2]") ) + { + goto done; + } + } + } + // Let's check to make sure the slot for this record is currently available: + char record_marker; + ssize_t presult = pread(rfp.fd, &record_marker, 1, rfp.flag_position); + if( presult < 0 ) + { + handle_errno(file, __func__, "pread() error"); + goto done; + } + + if( presult == 1 && record_marker == internal_newline ) + { + // The slot has something in it already: + file->io_status = FsDupWrite; // "22" + goto done; + } + // Either the record is available, or else the write is taking place at the + // end of the current file size. + + // Position the file pointer at the slot: + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + else + { + // We need to do a sequential write: + if( file->mode_char == 'a' ) + { + // Position the file pointer at the end: + fseek(file->file_pointer, 0, SEEK_END); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + } + + // Write out the data: + fwrite(location, length, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + if( file->record_area_max > length ) + { + size_t padding = file->record_area_max - length; + while(padding--) + { + fputc(internal_space, file->file_pointer); + } + } + + // Write out the rfm_microfocus "valid record" postamble: + fwrite(achPostamble, 1, 2, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + if( is_random ) + { + // Per the COBOL specification, put the file position back to where + // it was when we started this exercise: + fseek(file->file_pointer, rfp.current_file_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek(starting_pos) error") ) + { + goto done; + } + } + +done: + establish_status(file, -1); + } + +static void +sequential_file_write(cblc_file_t *file, + unsigned char *location, + size_t length, + int after, + int lines) + { + // This code handles SEQUENTIAL and LINE SEQUENTIAl + char ch = '\0'; + size_t characters_to_write; + + int lcount; + + if( lines < -1 ) + { + // We are using -666 for a form feed + ch = internal_ff; // Form feed + lcount = 1; + } + else if( lines == -1 ) + { + // -1 is a flag that no vertical control is requested + lcount = 0; + } + else if( lines == 0 ) + { + lcount = 1; + ch = internal_return; + } + else /* if( lines > 0 ) */ + { + lcount = lines; + ch = internal_newline; + } + + // By default, we write out the number of characters in the record area + characters_to_write = length; + + // That gets overridden if there is a record_length + if( file->record_length ) + { + int rdigits; + characters_to_write = (int)__gg__binary_value_from_field( + &rdigits, + file->record_length); + } + + if( file->org == file_line_sequential_e ) + { + // If file-sequential, then trailing spaces are removed: + while( characters_to_write > 0 + && location[characters_to_write-1] == internal_space ) + { + characters_to_write -= 1; + } + } + + if( after && file->org == file_line_sequential_e && ch == internal_newline ) + { + // In general, we terminate every line with a newline. Because this + // line is supposed to start with a newline, we decrement the line + // counter by one if we had already sent one. + if( lcount && ( file->recent_char == internal_newline + || file->recent_char == internal_ff) ) + { + lcount -= 1; + } + } + + if( after ) + { + while(lcount--) + { + fputc(ch, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error [3]") ) + { + goto done; + } + file->recent_char = ch; + } + // That might have been a formfeed; switch back to newline: + ch = internal_newline; + } + + switch(file->org) + { + case file_line_sequential_e: + if( characters_to_write ) + { + fwrite( location, + characters_to_write, + 1, + file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + file->recent_char = '\0'; + break; + + case file_sequential_e: + if( characters_to_write ) + { + // File sequential records can start off with a four-byte + // preamble. + + if( characters_to_write < file->record_area_min + || characters_to_write > file->record_area_max) + { + file->io_status = FsBoundWrite; // "44" + goto done; + } + + if( file->record_area_min != file->record_area_max ) + { + // Because of the min/max mismatch, we require a preamble: + // The first two bytes are the big-endian character count + unsigned char preamble[4] = + { + (unsigned char)(characters_to_write>>8), + (unsigned char)(characters_to_write), + 0, + 0 + }; + + fwrite( preamble, + 4, + 1, + file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + + fwrite( location, + characters_to_write, + 1, + file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + } + file->recent_char = '\0'; + break; + + default: + fprintf(stderr, + "%s(): Unhandled cbl_file_org_t %d\n", + __func__, + file->org); + exit(1); + break; + } + + if( after && lines>0 && file->org == file_line_sequential_e ) + { + // Special case: when AFTER NON-ZERO lines, we stick a newline on the + // end of this record: + fputc(ch, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error [4]") ) + { + goto done; + } + file->recent_char = internal_newline; + } + + if( !after ) + { + // We did the output BEFORE, so now it's time to send some internal_newlines + while(lcount--) + { + fputc(ch, file->file_pointer); + if( handle_ferror(file, __func__, "fputc() error [5]") ) + { + goto done; + } + file->recent_char = ch; + } + } + +done: + establish_status(file, -1); + } + +static void +indexed_file_write( cblc_file_t *file, + unsigned char *location, + size_t length, + bool is_random) + { + // This routine handles FILE WRITE to INDEXED files + + // Each record starts with a four-byte preamble. The first two bytes are + // a big-endian binary value indicating the length of the record (not + // including the preamble). The third byte is zero; the fourth byte is zero + // for a deleted record and one for an active record. + + file->errnum = 0; + file->io_status = FsErrno; + long position_to_write; + + int key_number = 1; // We are concerned with the primary key: + // Pick up our structure for the primary_key + file_index_t *file_index = &file->supplemental->indexes[key_number]; + + // Check to make sure the WRITE is consistent with the mode: + if( !is_random ) + { + // sequential mode is OUTPUT or EXTEND. We can only add things at the end + if( file->mode_char != 'w' && file->mode_char != 'a' ) + { + file->io_status = FsNoWrite; // "48" + goto done; + } + + if( file_index->key_to_position.size() == 0 ) + { + // We are dealing with an empty file, so we'll be writing at + // starting_position, which is set to the end + } + else + { + // The primary key for a new record in an indexed file in sequential + // access mode has to be greater than the biggest existing one: + + std::multimap, long>::const_reverse_iterator + last_element = file_index->key_to_position.crbegin(); + std::vector biggest_key = last_element->first; + + std::vector new_key = file_indexed_make_key( file, + key_number); + + // Quick & dirty comparison to make sure our new key is greater than + // the biggest_key: + bool okay = (memcmp(new_key.data(), biggest_key.data(), new_key.size() ) > 0); + if( !okay ) + { + // Create out-of-sequence INVALID KEY condition + file->io_status = FsKeySeq; // "21" + goto done; + } + // We are allowed to do the write. Because this is "w" or "a", + // it will be at the end + } + } + else + { + // Because access is random or dynamic the mode has to be OUTPUT or I-O + if( file->mode_char != 'w' && file->mode_char != '+' ) + { + file->io_status = FsNoWrite; // "48" + goto done; + } + + // We are allowed to do the write, but only if there will be no key + // violations as a result: + + for(size_t key_number=1; + key_numbersupplemental->indexes.size(); + key_number++) + { + if( file->supplemental->uniques[key_number] ) + { + long record_position = file_indexed_first_position(file, key_number); + if( record_position != -1 ) + { + // No can do, because we already have a unique key with that value + file->io_status = FsDupWrite; // "22" + goto done; + } + } + } + + // This record is not in the data file; figure out where to put it + if( file->mode_char == '+' ) + { + // This is a '+' for I-O, so we can write into a hole. + + // See if we have a hole that is the right size: + bool found_hole = false; + for( size_t i=0; isupplemental->holes.size(); i++ ) + { + if( file->supplemental->holes[i].size == length ) + { + // We found a hole, and we're going to use it + + // Pick up the position + position_to_write = file->supplemental->holes[i].location; + + // Get rid of the hole we just filled: + file->supplemental->holes[i] = file->supplemental->holes.back(); + file->supplemental->holes.pop_back(); + + // Position the file, ready to write: + fseek(file->file_pointer, position_to_write, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + found_hole = true; + break; + } + } + if( !found_hole ) + { + // There is no hole, so make sure we are writing at the end + fseek(file->file_pointer, 0, SEEK_END); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + } + } + + // The file is positioned for where the write is to take place. And we know + // that there will be no key violation when we update the indices. + + position_to_write = ftell(file->file_pointer); + if( handle_ferror(file, __func__, "ftell() error") ) + { + goto done; + } + + // We are currently located where the new data must be written. + unsigned char ach[4]; + ach[0] = (unsigned char)(length>>8); + ach[1] = (unsigned char)length; + ach[2] = 0; + ach[3] = 1; + + // Write out the preamble: + fwrite(ach, 4, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + // Write out the data: + fwrite(location, length, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fwrite() error") ) + { + goto done; + } + + file_indexed_update_indices(file, position_to_write); + +done: + establish_status(file, -1); + } + +static void +__io__file_write( cblc_file_t *file, + unsigned char *location, + size_t length, + int after, + int lines, + int is_random ) + { + // After an epic discussion with Marty, a determination has been made to + // ignore the IBM and ISO specifications, and treat an unadorned WRITE as + // if it were the same as WRITE xxx BEFORE 1 LINE + + file->errnum = 0; + file->io_status = FsErrno; + + if( !file->file_pointer ) + { + // Attempting to write a file that isn't open + file->io_status = FsNoWrite; // "48" + goto done; + } + + switch( file->access ) + { + case file_access_seq_e: + if( file->mode_char != 'w' && file->mode_char != 'a' ) + { + // File is open, but not in OUTPUT or EXTEND mode + file->io_status = FsNoWrite; // "48" + goto done; + } + break; + + case file_access_rnd_e: + case file_access_dyn_e: + if( file->mode_char != 'w' && file->mode_char != '+' ) + { + // File is open, but not in I-O or OUTPUT or + file->io_status = FsNoWrite; // "48" + goto done; + } + break; + + default: + warnx("%s(): Thanks for playing. Next contestant, please", __func__); + abort(); + break; + } + + if( file->record_length ) + { + int rdigits; + length = (size_t)__gg__binary_value_from_field( &rdigits, + file->record_length); + } + + switch(file->org) + { + case file_line_sequential_e: + case file_sequential_e: + sequential_file_write(file, location, length, after, lines); + break; + + case file_relative_e: + { + relative_file_write(file, location, length, is_random); + break; + } + + case file_indexed_e: + { + indexed_file_write(file, location, length, is_random); + break; + } + + default: + fprintf(stderr, "%s(): Unhandled cbl_file_org_t %d\n", + __func__, + file->org); + exit(1); + break; + } +done: + establish_status(file, -1); + if( file->io_status < FhNotOkay ) + { + file->flags |= file_flag_existed_e; + } + file->prior_op = file_op_write; + } + +static void +line_sequential_file_read( cblc_file_t *file) + { + file->errnum = 0; + file->io_status = FsErrno; + size_t characters_read = 0; + size_t remaining; + bool hit_eof; + + // According to IBM: + + // Characters are read one at a time until: + // - A delimiter is reached. It is discarded, and the + // record area is filled with spaces. + // - The entire record area is filled. If the next unread + // character is the delimiter, it is discarded. Otherwise, + // it becomes the first character read by the next READ + // - EOF is encountered; the remainder of the record area + // is filled with spaces. + + // This contradicts the ISO/IEC 2014 standard, which says + // in section 14.9.29.3, paragraph 14) on page 554 that excess + // characters are discarded, and too-short records have + // characters to the right as undefined. I'm going with IBM, + // it makes more sense to me. + + // We first stage the data into the record area. + int ch; + + long fpos = ftell(file->file_pointer); + if( handle_ferror(file, __func__, "ftell() error") ) + { + fpos = -1; + goto done; + } + + hit_eof = false; + while( characters_read < file->record_area_max ) + { + ch = fgetc(file->file_pointer); + file->errnum = ferror(file->file_pointer); + if( ch == file->delimiter ) + { + break; + } + if( ch == file->delimiter || ch == EOF ) + { + hit_eof = true; + clearerr(file->file_pointer); + break; + } + if( handle_ferror(file, __func__, "fgetc() error") ) + { + fpos = -1; + goto done; + } + file->default_record->data[characters_read] = (char)ch; + characters_read += 1; + } + remaining = characters_read; + while(remaining < file->record_area_max ) + { + // Space fill shorty records + file->default_record->data[remaining++] = internal_space; + } + + if( hit_eof && !characters_read) + { + // We got an end-of-file without characters + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + } + else if( hit_eof ) + { + // We got an end-of-file whilst reading characters + // Override the FsEofSeq. We'll get an actual EOF if the programmer + // does another READ: + file->io_status = FsErrno; + } + else if (characters_read < file->record_area_max) + { + // Just discard an early record delimiter + file->io_status = FsRecordLength; // "04" + } + else // We filled the whole record area. Look ahead one character + { +#ifdef POSSIBLY_IBM + // In this code, unread characters before the internal_newline + // are read next time. See page 133 of the IBM Language Reference + // Manual: "If the first unread character is the record delimiter, it + // is discarded. Otherwise, the first unread character becomes the first + // character read by the next READ statement." + ch = fgetc(file->file_pointer); + file->errnum = ferror(); + // If that next character isn't a delimiter, put it back: + if( ch != file->delimiter && ch != EOF) + { + ungetc(ch, file->file_pointer); + } + else if( handle_ferror(file->file_pointer, __func__, "fgetc() error") ) + { + fpos = -1; + goto done; + } +#else + // In this code, extra characters before the internal_newline + // are read next time are discarded. GnuCOBOL works this way, and + // the Michael Coughlin "Beginning COBOL" examples require this mode. + // The ISO/IEC 2014 standard is silent on the question of LINE + // SEQUENTIAL; it describes only SEQUENTIAL. + for(;;) + { + ch = fgetc(file->file_pointer); + file->errnum = ferror(file->file_pointer); + // We can't use handle_ferror() directly, because an EOF is + // a legitimate way to end the last line. + if( ch == file->delimiter || ch == EOF) + { + clearerr(file->file_pointer); + break; + } + if( ferror(file->file_pointer) + && handle_ferror(file, __func__, "fgetc() error") ) + { + fpos = -1; + goto done; + } + file->io_status = FsRecordLength; // "04" + } +#endif + } + + if( file->record_length ) + { + __gg__int128_to_field(file->record_length, + characters_read, + 0, + truncation_e, + NULL); + } +done: + establish_status(file, fpos); + } + +static size_t +sequential_file_read( cblc_file_t *file) + { + unsigned char preamble[4]; + size_t characters_read; + size_t bytes_in_record; + size_t bytes_to_read; + long fpos; + + file->errnum = 0; + + if( file->io_status >= FsEofSeq ) // "10" + { + // There is a special error code for trying to read a file after an error + // or after an EOF has been encountered + file->io_status = FsReadError; // "46" + fpos = -1; + goto done; + } + + file->io_status = FsErrno; + + fpos = ftell(file->file_pointer); + if( handle_ferror(file, __func__, "ftell() error") ) + { + fpos = -1; + goto done; + } + + if( file->record_area_min != file->record_area_max ) + { + // Because of the different sizes, we are expecting a preamble: + + // An error at this point is either an error, or a true end-of-file. + characters_read = fread(preamble, 1, 4, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + // This also comes back true for an ordinary end-of-file + fpos = -1; + goto done; + } + + if( characters_read != 4 ) + { + // If the preamble is incomplete, treat that as an EOF + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + fpos = -1; + goto done; + } + + // Extract the count of bytes in the record from the preamble + bytes_in_record = ((size_t)preamble[0]<<8) + preamble[1]; + } + else + { + // Because the min and max are the same, we figure on reading that many + // characters: + bytes_in_record = file->record_area_max; + } + + + // We are now going to read that many bytes from the file into the record area + // Let's make sure that bogus input doesn't cause us to fall off the end of + // the world: + bytes_to_read = std::min( bytes_in_record, + file->record_area_max); + + characters_read = fread(file->default_record->data, + 1, + bytes_to_read, + file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + fpos = -1; + goto done; + } + if( characters_read < bytes_in_record ) + { + memset(file->default_record->data, internal_space, bytes_to_read); + file->io_status = FsEofSeq; // "10" + fpos = -1; + goto done; + } + + // Let the caller know if we got too few or too many characters + if( bytes_in_record < file->record_area_min + || bytes_in_record > file->record_area_max ) + { + file->io_status = FsRecordLength; // "04" + } + + if( bytes_in_record > file->record_area_max ) + { + // Let's fix the misalignment + fseek(file->file_pointer, + bytes_in_record - file->record_area_max, + SEEK_CUR); + } + + if( file->record_length ) + { + __gg__int128_to_field(file->record_length, + characters_read, + 0, + truncation_e, + NULL); + } +done: + establish_status(file, fpos); + return characters_read; + } + +static void +relative_file_read_varying( cblc_file_t *file, + int where) + { + // where -2 PREVIOUS + // where -1 NEXT + // where 0 who the hell knows + // where 1 or more: random read + + bool is_random = where > 0; + + file->errnum = 0; + file->io_status = FsErrno; + + relative_file_parameters rfp; + + size_t characters_read = 0; + long fpos = -1; + size_t payload_length; + + if( where >= 1 ) + { + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + RESPECT_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + if( rfp.record_position >= rfp.file_size ) + { + // We're falling off the end of the file, which means our key doesn't + // exist + file->io_status = FsNotFound; // "23" + goto done; + } + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + else if( where == -1) + { + // This is a sequential NEXT read of a RELATIVE file + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + IGNORE_LIMITS, + INIT_KEY, + is_random) ) + { + goto done; + } + } + else + { + warnx("Whatever are we doing here?"); + abort(); + } + + // We are now poised to read a record, + for(;;) + { + if( !rfp.inside_existing_file ) + { + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + + fread(&payload_length, 8, 1, file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + fpos = -1; + goto done; + } + + if( payload_length ) + { + // We have a good record to read: + + // Read the characters into the record area: + fread(file->default_record->data, + 1, + file->record_area_max, + file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + // Having read that that data, set up for a subsequent delete/rewrite. + // Set fpos to the current_file_position, and then update the current + // file position. + fpos = rfp.current_file_position; + + // We need to change the file position pointer to point to the next + // record. + + rfp.current_file_position += rfp.record_size; + fseek(file->file_pointer, + rfp.current_file_position, + SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + fpos = -1; + goto done; + } + + break; + } + else + { + // There isn't a record in this slot + if( where == -1 ) + { + // But we are in next_record mode. It is our duty and obligation + // to skip merrily through the file looking for the next valid + // record for the lazy bums who called us. + rfp.record_position += rfp.record_size; + rfp.flag_position += rfp.record_size; + rfp.inside_existing_file + = rfp.record_position + rfp.record_size <= rfp.file_size; + rfp.key_value = 1 + rfp.record_position + / (rfp.preamble_size + + rfp.payload_size + + rfp.postamble_size); + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + rfp.current_file_position = rfp.record_position; + continue; + } + break; + } + } + + characters_read = payload_length; + if( characters_read == 0 ) + { + file->io_status = FsNotFound; // "23" + goto done; + } + else + { + if( where < 0 ) + { + // We did a FORMAT 1 read, so we need to update the key, if there is one + if( file->keys[0] ) + { + long max_key = max_value(file->keys[0]); + if( rfp.key_value >= max_key ) + { + // This is an oddball COBOL error: A sequential read would result in + // reading a record whose relative record number is too big for + // file->key to hold + file->io_status = FsEofRel; // "14" + goto done; + } + __gg__int128_to_field(file->keys[0], + rfp.key_value, + 0, + truncation_e, + NULL); + } + } + } +done: + if( file->record_length ) + { + __gg__int128_to_field(file->record_length, + payload_length, + 0, + truncation_e, + NULL); + } + establish_status(file, fpos); + } + +static void +relative_file_read( cblc_file_t *file, + int where) + { + // where -2 means PREVIOUS + // where -1 means NEXT + // where 0 means random read, based on the key + + if( file->record_area_min != file->record_area_max ) + { + return relative_file_read_varying(file, where); + } + + bool is_random = where > 0; + + file->errnum = 0; + file->io_status = FsErrno; + + relative_file_parameters rfp; + + size_t characters_read = 0; + long fpos = -1; + + if( where >= 1 ) + { + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + RESPECT_LIMITS, + DONT_INIT_KEY, + is_random) ) + { + goto done; + } + + if( rfp.record_position >= rfp.file_size ) + { + // We're falling off the end of the file, which means our key doesn't + // exist + file->io_status = FsNotFound; // "23" + goto done; + } + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + else if( where == -1) + { + // This is a sequential NEXT read of a RELATIVE file + if( relative_file_parameters_get( rfp, + rfm_microfocus_e, + file, + IGNORE_LIMITS, + INIT_KEY, + is_random) ) + { + goto done; + } + } + else + { + warnx("Whatever are we doing here?"); + abort(); + } + + // The following code is predicated on rfm_microfocus_e. + + // We are now poised to read a record, provided the flag byte is + // indicates this is a good record + for(;;) + { + if( !rfp.inside_existing_file ) + { + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + char record_marker; + if( pread(rfp.fd, &record_marker, 1, rfp.flag_position) <= 0) + { + goto done; + } + if(record_marker == internal_newline) + { + // We have a good record to read: + + // We need to change the file_position_pointer to reflect any + // preamble: + if( rfp.preamble_size ) + { + fseek(file->file_pointer, rfp.preamble_size, SEEK_CUR); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + } + // Read the characters into the record area: + characters_read = fread(file->default_record->data, + 1, + file->record_area_max, + file->file_pointer); + if( handle_ferror(file, __func__, "fread() error") ) + { + goto done; + } + // Having read that that data, set up for a subsequent delete/rewrite. + // Set fpos to the current_file_position, and then update the current + // file position. + fpos = rfp.current_file_position; + + // We need to change the file position pointer to point to the next + // record. + + rfp.current_file_position += rfp.record_size; + fseek(file->file_pointer, + rfp.current_file_position, + SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + fpos = -1; + goto done; + } + + break; + } + else + { + // There isn't a record in this slot + if( where == -1 ) + { + // But we are in next_record mode. It is our duty and obligation + // to skip merrily through the file looking for the next valid + // record for the lazy bums who called us. + rfp.record_position += rfp.record_size; + rfp.flag_position += rfp.record_size; + rfp.inside_existing_file + = rfp.record_position + rfp.record_size <= rfp.file_size; + rfp.key_value = 1 + rfp.record_position + / (rfp.preamble_size + + rfp.payload_size + + rfp.postamble_size); + + fseek(file->file_pointer, rfp.record_position, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + goto done; + } + rfp.current_file_position = rfp.record_position; + continue; + } + break; + } + } + + if( characters_read == 0 ) + { + file->io_status = FsNotFound; // "23" + goto done; + } + else + { + if( where < 0 ) + { + // We did a FORMAT 1 read, so we need to update the key, if there is one + if( file->keys[0] ) + { + long max_key = max_value(file->keys[0]); + if( rfp.key_value >= max_key ) + { + // This is an oddball COBOL error: A sequential read would result in + // reading a record whose relative record number is too big for + // file->key to hold + file->io_status = FsEofRel; // "14" + goto done; + } + __gg__int128_to_field(file->keys[0], + rfp.key_value, + 0, + truncation_e, + NULL); + } + } + } +done: + if( file->record_length ) + { + __gg__int128_to_field(file->record_length, + characters_read, + 0, + truncation_e, + NULL); + } + establish_status(file, fpos); + } + +static void +indexed_file_read( cblc_file_t *file, + int key_number) + { + long record_length; + int flag; + int read_res; + + if( key_number == 0 ) + { + // This is an implicit next + key_number = -1; + } + + size_t characters_read = 0; + file_index_t *file_index; + long fpos = -1; + + if( key_number >= 1 ) + { + // It is meat and potatoes time. We need to pick up the first record + // with the specified key: + file->errnum = 0; + file->io_status = FsErrno; + + file->recent_key = key_number; + file_index = &file->supplemental->indexes[key_number]; + fpos = file_indexed_first_position(file, key_number); + if( fpos == -1 ) + { + file->io_status = FsNotFound; // "23" + goto done; + } + fpos = file_indexed_first_position(file, key_number); + file_index->current_iterator++; + } + else if( key_number == -1 ) + { + // We are ready to do a sequential read of an INDEXED file + + // There is a special code for trying to read after a preceding unsuccessful + // statement: + + if( file->io_status >= FsEofSeq ) // "10" + { + file->io_status = FsReadError; // "46" + goto done; + } + + file->errnum = 0; + file->io_status = FsErrno; + + file_index = &file->supplemental->indexes[file->recent_key]; + + // When you arrive here, the current_indicator points to the iterator + // *after* the prior successful read + if( file_index->current_iterator == file_index->key_to_position.end() ) + { + // We have hit the end of keys + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + + fpos = file_index->current_iterator->second; + + if( file_index->current_iterator == file_index->key_to_position.end() ) + { + __gg__abort("indexed_file_read(): fell off of file_index->key_to_position"); + } + file_index->current_iterator++; + } + else if( key_number == -2 ) + { + // We are ready to do a sequential read PREVIOUS of an INDEXED file + + // There is a special code for trying to read after a preceding unsuccessful + // statement: + if( file->io_status >= FsEofSeq ) // "10" + { + file->io_status = FsReadError; // "46" + goto done; + } + + file->errnum = 0; + file->io_status = FsErrno; + + file_index = &file->supplemental->indexes[file->recent_key]; + + /* We need to do a little thinking. After an OPEN or START, + * file_index->current_iterator points to the next record to read for + * either a READ NEXT or READ PREVIOUS. + * + * But after a READ, a subsequent READ PREVIOUS needs to back the iterator + * down by 2 to get the correct record. + */ + + if( file->prior_op == file_op_read ) + { + // We just read record 10, so the iterator points to 11. We need to back + // it down to 9, if we can. (There might not be enough records) + + // We know we can back it down at least one record + file_index->current_iterator--; // Make it point back to 10 + if( file_index->current_iterator == file_index->key_to_position.begin() ) + { + // but we can't back it down another + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + file_index->current_iterator--; // Make it point back to 9 + } + else if( file->prior_op == file_op_delete ) + { + if( file->prior_read_location == -1 ) + { + // The prior operation deleted the record we are set up to read. + // Let's finesse the positioning. + if( file_index->current_iterator == file_index->key_to_position.end() ) + { + // We have hit the end of the keys. + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + file_index->current_iterator--; + } + } + else + { + // This must be after an OPEN or START. Check to make sure that the + // file isn't actually empty + + if( file_index->current_iterator == file_index->key_to_position.end() ) + { + // We have hit the end of the keys. + file->io_status = FsEofSeq; // "10" + file->prior_read_location = -1; + goto done; + } + } + + // We are ready to proceed + + fpos = file_index->current_iterator->second; + if( file_index->current_iterator == file_index->key_to_position.end() ) + { + __gg__abort("indexed_file_read(): fell off of file_index->key_to_position"); + } + file_index->current_iterator++; + } + + // fpos is where the data are: + fseek(file->file_pointer, fpos, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() error") ) + { + fpos = -1; + goto done; + } + + read_res = read_an_indexed_record(file, + file->record_area_max, + record_length, + flag); + if( read_res ) + { + // We hit an end of file or an error + fpos = -1; + goto done; + } + + if(flag != 1) + { + warnx("The file isn't right; key number %d found a deleted record", + key_number); + abort(); + } + + characters_read = record_length; + +done: + if( file->record_length ) + { + __gg__int128_to_field(file->record_length, + characters_read, + 0, + truncation_e, + NULL); + } + establish_status(file, fpos); + } + +static void +__io__file_read(cblc_file_t *file, + int where) + { + // where = -2 means PREVIOUS + // where = -1 means NEXT + // where = 1 or more means key N, where N is one-based + + file->errnum = 0; + + if( !(file->flags & file_flag_existed_e) + && (file->flags & file_flag_optional_e)) + { + // Trying to read a file that didn't exist during file_open. + if( file->org == file_sequential_e || file->org == file_line_sequential_e ) + { + if( file->io_status < FhNotOkay ) + { + // This is a format 1 read + file->io_status = FsEofSeq; // "10" + } + else + { + file->io_status = FsReadError; // "46" + } + establish_status(file, -1); + return; + } + else + { + // The indexed or relative file didn't exist, so set an INVALID KEY + // condition: + if( where <= 0 ) + { + if( file->io_status < FhNotOkay ) + { + // This is a format 1 read + file->io_status = FsEofSeq; // "10" + } + else + { + file->io_status = FsReadError; // "46" + } + establish_status(file, -1); + } + else + { + // This is a format 2 read + file->io_status = FsNotFound; // "23" + establish_status(file, -1); + } + return; + } + } + + if( !file->file_pointer ) + { + // Attempting to read a file that isn't open + file->io_status = FsReadNotOpen; // "47" + establish_status(file, -1); + return; + } + + if( file->mode_char != 'r' && file->mode_char != '+' ) + { + // The file is open, but not in INPUT or I-O mode: + file->io_status = FsReadNotOpen; // "47" + establish_status(file, -1); + return; + } + + switch(file->org) + { + case file_line_sequential_e: + { + line_sequential_file_read(file); + break; + } + + case file_sequential_e: + { + sequential_file_read(file); + break; + } + + case file_relative_e: + { + relative_file_read(file, where); + break; + } + + case file_indexed_e: + { + indexed_file_read(file, where); + break; + } + + default: + fprintf(stderr, + "%s(): Unhandled cbl_file_org_t %d\n", + __func__, + file->org); + exit(1); + break; + } + if( file->io_status < FhNotOkay ) + { + file->flags |= file_flag_existed_e; + } + file->prior_op = file_op_read; + } + +static void +file_indexed_open(cblc_file_t *file) + { + // The file was supposed to be open when you got here. + if( !file->file_pointer ) + { + __gg__abort("file_indexed_open(): file_pointer is NULL"); + } + + file->supplemental = new supplemental_t; + + // We need one multimap for each key. Whenever we are told about a key, it'll + // be by key_number. key_number 1 is by convention the primary key. There + // will be no key_number zero, so we are going to start our vector of indexes + // with an empty placeholder: + + unsigned char *stash = NULL; + + file_index_t file_index; + file->supplemental->indexes.push_back(file_index); + file->supplemental->uniques.push_back(0); + + // Add one entry to the indexes for each key number: + int current_key_number = 0; + size_t index = 0; + while(file->key_numbers[index] != -1) + { + if( file->key_numbers[index] != current_key_number ) + { + file_index_t file_index; + file->supplemental->indexes.push_back(file_index); + current_key_number = file->key_numbers[index]; + file->supplemental->uniques.push_back(file->uniques[index]); + } + index += 1; + } + + // To build indexes, we need to be at the beginning: + fseek(file->file_pointer, 0, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() after fopen() failed") ) + { + goto done; + } + + switch( file->mode_char ) + { + case 'w': + // OUTPUT mode causes an empty file to be created, so the indices + // are empty as well + break; + + case 'r': + case 'a': + case '+': + if( file->flags & file_flag_existed_e ) + { + // We need to open the file for reading, and build the + // maps for each index: + static size_t fname_size = MINIMUM_ALLOCATION_SIZE; + static char *fname = (char *)malloc(fname_size); + + internal_to_console(&fname, + &fname_size, + file->filename, strlen(file->filename)); + + // We are going to scan through the entire file, building index + // entries for each record. + + // It should already be at the beginning: + if( ftell(file->file_pointer) != 0 ) + { + __gg__abort("file_indexed_open():" + " file_pointer should be at the beginning"); + } + + // Stash the existing record area: + stash = (unsigned char *)malloc(file->record_area_max); + memcpy( stash, + file->default_record->data, + file->record_area_max); + + for(;;) + { + // Remember where we are right now: + long record_length; + int flag; + long record_position = ftell(file->file_pointer); + if( handle_ferror(file, __func__, "ftell() error") ) + { + goto done; + } + + int read_result = read_an_indexed_record( file, + file->record_area_max, + record_length, + flag); + if( read_result == 1 ) + { + // Don't panic; it's just an end-of-file + break; + } + else if( read_result > 1 ) + { + // It was an error of some kind + goto done; + } + + if( flag == 1 ) + { + // We have a good record in our record area: + + if( !file_indexed_update_indices(file, record_position) ) + { + // There must have been a duplicate UNIQUE index, or some other + // problem. + goto done; + } + } + else + { + // This is a hole in the file; make it available for a WRITE or + // EXTEND + file_hole_t hole = {record_position, (size_t)record_length}; + file->supplemental->holes.push_back(hole); + } + } + + file->io_status = FsErrno; + fseek(file->file_pointer, 0, SEEK_SET); + if( handle_ferror(file, __func__, "fseek() after fopen() failed") ) + { + goto done; + } + } + break; + + default: + warnx( "%s(): This is weird. mode_char is '%c' (%d)?\n", + __func__, + file->mode_char, + file->mode_char); + __gg__abort("file_indexed_open(): Unknown mode_char"); + break; + } +done: + // We need to initialize the iterators for every index: + for( size_t i=1; isupplemental->indexes.size(); i++ ) + { + file->supplemental->indexes[i].current_iterator = + file->supplemental->indexes[i].key_to_position.begin(); + file->supplemental->indexes[i].ending_iterator = + file->supplemental->indexes[i].key_to_position.end(); + } + file->recent_key = 1; + + if( stash ) + { + // Restore the original record area: + memcpy( file->default_record->data, + stash, + file->record_area_max); + free(stash); + } + + fseek(file->file_pointer, 0, SEEK_SET); + handle_ferror(file, __func__, "fseek() error"); + + } + +static void +file_indexed_close(cblc_file_t *file) + { + delete file->supplemental; + file->supplemental = NULL; + } + +static void +report_open_failure(const char *type, + const char *structure_name, + const char *filename) + { + bool quiet = true; + if( !quiet ) + { + if( getenv(filename) ) + { + fprintf(stderr, + "Trying to 'OPEN %s %s %s -> \"%s\"', which doesn't exist\n", + type, + structure_name, + filename, + getenv(filename)); + } + else + { + fprintf(stderr, + "Trying to 'OPEN %s %s \"%s\"', which doesn't exist\n", + type, + structure_name, + filename); + } + } + } + +extern "C" +void +__gg__file_reopen(cblc_file_t *file, int mode_char) + { + // This is a useful, although scary, little helper. The file must not be + // open. The file->filename must be valid, as must the file_name_quoted_e flag. + // You can see it used in __gg__file_open. You can also see it in + // __gg__sort_workfile, where the workfile is passed as open for read, and + // which needs to be closed and reopened first in "r" and then "w" modes. + + // Note that when closing for reopening, you must simply use fclose() and not + // __gg__file_close(). The second one does bookkeeping and cleanup that is + // not appropriate here. + + bool the_file_exists; + bool random_access_mode; + char achMode[3]; + + // Stash the mode_char for later analysis during READ and WRITE operations + file->mode_char = mode_char; + char *trimmed_name; + trimmed_name = get_filename(file, !!(file->flags & file_name_quoted_e)); + if( !trimmed_name[0] ) + { + bool all_spaces = true; + for(size_t i=0; ifilename); i++) + { + if( file->filename[i] != internal_space ) + { + all_spaces = false; + } + break; + } + if( all_spaces ) + { + warnx("Warning: %s specified with a filename that is all spaces", + file->name); + file->io_status = FsNameError; // "31" + goto done; + } + + static size_t fname_size = MINIMUM_ALLOCATION_SIZE; + static char *fname = (char *)malloc(fname_size); + internal_to_console(&fname, + &fname_size, + file->filename, + strlen(file->filename)); + warnx( "%s(): There is no environment variable named \"%s\"\n", + __func__, + fname); + file->io_status = FsNoFile; // "35" + goto done; + } + + // achMode is the mode string that gets passed down below to fopen(). + random_access_mode = ( file->access == file_access_rnd_e + || file->access == file_access_dyn_e); + the_file_exists = access(trimmed_name, F_OK) == 0; + file->flags |= the_file_exists ? file_flag_existed_e : 0 ; + + // We have four operations: INPUT (r) OUTPUT (w) I-O (+) and EXTEND (a) + // INPUT and I-O and EXTEND have different results based on is_optional + // and whether or not the file exists. + // Various modification take place if random_access_mode is true + + if( the_file_exists ) + { + switch(mode_char) + { + case 'r': + // OPEN INPUT + // We need a vanilla read-only file: + strcpy(achMode, "r"); + break; + + case 'w': + // OPEN OUTPUT + // This syntax means create a new file, or overwrite an existing + // one. For files with random access mode, we need to be + // able to read as well as write, because we have to be able + // to ascertain that a record slot is empty in the event that + // the programmer tries to write to the same slot twice: + if( random_access_mode ) + { + strcpy(achMode, "w+"); + } + else + { + strcpy(achMode, "w"); + } + break; + + case 'a': + // EXTEND is for sequential files: + strcpy(achMode, "a"); + break; + + case '+': + // I-O + // We need to be able to read and write the existing file. + strcpy(achMode, "r+"); + break; + + default: + fprintf(stderr, + "%s(): We were given an unknown mode_char %d\n", + __func__, + mode_char); + exit(1); + break; + } + } + else + { + // The file *doesn't* exist + switch(mode_char) + { + case 'r': + // OPEN INPUT, but the file doesn't exist: + if( file->flags & file_flag_optional_e ) + { + // This is a weird condition. OPTIONAL means "flag it as sort of + // open but the first read causes AT END or INVALID KEY condition. + file->io_status = FsUnavail; // "05" + goto done; + } + else + { + report_open_failure("INPUT", file->name, trimmed_name); + file->io_status = FsNoFile; // "35" + goto done; + } + break; + + case 'w': + // OPEN OUTPUT + // This syntax means create a new file, or overwrite an existing + // one. For files with random access mode, we need to be + // able to read as well as write, because we have to be able + // to ascertain that a record slot is empty in the event that + // the programmer tries to write to the same slot twice: + if( random_access_mode ) + { + strcpy(achMode, "w+"); + } + else + { + strcpy(achMode, "w"); + } + break; + + case 'a': + // EXTEND + if( file->flags & file_flag_optional_e ) + { + if( random_access_mode ) + { + // For files that might be sequential or random: + strcpy(achMode, "a+"); + } + else + { + // For pure sequential files, we just do a straight "a" + strcpy(achMode, "a"); + } + file->io_status = FsUnavail; // "05" + } + else + { + // Trying to extend a non-optional non-existing file is against the rules + report_open_failure("EXTEND", file->name, trimmed_name); + file->io_status = FsNoFile; // "35" + goto done; + } + break; + + case '+': + // I-O + if( file->flags & file_flag_optional_e ) + { + // We need to be able to read and write a new file. + strcpy(achMode, "w+"); + file->io_status = FsUnavail; // "05" + } + else + { + report_open_failure("I-O", file->name, trimmed_name); + file->io_status = FsNoFile; // "35" + goto done; + } + break; + + default: + fprintf(stderr, + "%s(): We were given an unknown mode_char %d\n", + __func__, + mode_char); + exit(1); + break; + } + } + + file->file_pointer = fopen(trimmed_name, achMode); + if( file->file_pointer == NULL ) + { + file->errnum = errno; + // We were unable to open the file + switch(mode_char) + { + case 'r': + case 'a': + case '+': + file->io_status = FsNoFile; // "35" + goto done; + break; + + case 'w': + file->io_status = FsOsError; // "30" + goto done; + break; + } + } + file->errnum = ferror(file->file_pointer); + + // If this was a OPEN EXTEND, we want the file positioned at the + // the very end (which it won't be when achMode is "r+" + if( mode_char == 'a' ) + { + fseek(file->file_pointer, 0, SEEK_END); + if( handle_ferror(file, __func__, "fseek() after fopen() failed") ) + { + goto done; + } + } + if( file->org == file_indexed_e ) + { + file_indexed_open(file); + } + file->recent_char = '\0'; + + done: + file->prior_op = file_op_open; + } + +static void +__io__file_open(cblc_file_t *file, + char *filename, + int mode_char, + int is_quoted) + { + // Filename is a pointer to a malloc() buffer. + + // The complication: A filename can be literal text, it can be from a COBOL + // alphanumeric variable, or it can be the name of an environment variable + // that contains the actual name of the file. The consequence is that if + // you want to call __gg__file_open from anywhere except the parser_file_open + // routine, then you had best really know what you are doing. + + file->errnum = 0; + file->io_status = FsErrno; + if( file->file_pointer ) + { + // The file is already open: + file->io_status = FsIsOpen; // "41" 14.9.26.3 Paragraph 1 + } + else + { + // filename is the result of a strdup or malloc. We will free() it at + // file close time. + file->filename = filename; + file->flags &= ~file_name_quoted_e; + file->flags |= is_quoted ? file_name_quoted_e : 0; + + __gg__file_reopen(file, mode_char); + } + establish_status(file, -1); + file->prior_op = file_op_open; + } + +static void +__io__file_close( cblc_file_t *file, int how ) + { + // We are forcing line-sequential files to end with a newline: + + // if( file->org == file_line_sequential_e + // && ( file->mode_char == 'w' || file->mode_char == 'a' ) + // && file->recent_char != internal_newline ) + // { + // int ch = internal_newline; + // fputc(ch, file->file_pointer); + // if( handle_ferror(file, __func__, "fputc() error [6]") ) + // { + // goto done; + // } + // file->recent_char = ch; + // } + + errno = 0; + file->io_status = FsErrno; + long fpos = -1; + if( !file->file_pointer ) + { + // Attempting to close a file that isn't open: + file->io_status = FsCloseNotOpen; // "42" 14.9.6.3 Paragraph 1 + goto done; + } + + if( how == file_close_reel_unit_e ) + { + // Closing a REEL unit. Leave the file open, and return "07" + file->io_status = FsNotaTape; // "07" + + // We have to leave the file position alone: + fpos = ftell(file->file_pointer); + goto done; + } + + if( fclose(file->file_pointer) != 0 ) + { + handle_ferror(file, __func__, "fclose() error"); + } + file->file_pointer = NULL; + + if( file->org == file_indexed_e ) + { + file_indexed_close(file); + } + + // The filename can be from a COBOL alphanumeric variable, which means it can + // between a file_close and a subsequent file_open. So, we get rid of it + // here + free(file->filename); + file->filename = NULL; + + done: + establish_status(file, fpos); + file->prior_op = file_op_close; + } + +static cblc_file_t *stashed; + +cblc_file_t * +__gg__file_stashed() + { + return stashed; + } + +extern "C" +void +__gg__file_stash( cblc_file_t *file ) + { + ::stashed = file; + } + + /* + * The following constitutes a proposal for a public API to gcobol I/O. + * + * The class gcobol_io_t would be in a public header file that + * would be used by any library that provides an I/O + * implementation. Additionally, that header would be where + * cblc_file_t is defined, and where the valid file status values + * (and relops) are enumerated. + * + * The library contructs the class, providing its own pointers, + * and supplies a known function, gcobol_fileops, to return + * it. gcobol-compiled programs call the functions, or others + * supplied by a different implementation, through the pointers. + * + * This design makes it possible to run the same code, unaltered, + * simply by relinking. + * + * This design is commonly used, and is similar to the one used in + * GnuCOBOL. One difference is that the file status is captured + * in the cblc_file_t, whereas in GnuCOBOL it is the return value. + * + * There is no provision for using more than one implemetation at + * a time in the same program, as would be needed for CODE-SET + * support. To achieve that in C++ without dynamic linking, there + * would have to be a set of known implementations, each with its + * own namespace, in which gcobol_fileops would be defined. + */ + +class gcobol_io_t { +public: + static const char constexpr marquee[64] = "libgcobol: gfileio.cc"; + + typedef void (open_t)( cblc_file_t *file, + char *filename, + int mode_char, + int is_quoted ); + typedef void (close_t)( cblc_file_t *file, + int how ); + typedef void (start_t)( cblc_file_t *file, + int relop, // needs enum + int first_last_key, + size_t length ); + typedef void (read_t)( cblc_file_t *file, + int where ); + typedef void (write_t)( cblc_file_t *file, + unsigned char *location, + size_t length, + int after, + int lines, + int is_random ); + typedef void (rewrite_t)( cblc_file_t *file, + size_t length, bool is_random ); + typedef void (delete_t)( cblc_file_t *file, + bool is_random ); + + open_t *Open; + close_t *Close; + start_t *Start; + read_t *Read; + write_t *Write; + rewrite_t *Rewrite; + delete_t *Delete; + + gcobol_io_t() + : Open(NULL) + , Close(NULL) + , Start(NULL) + , Read(NULL) + , Write(NULL) + , Rewrite(NULL) + , Delete(NULL) + {} + + gcobol_io_t( open_t *Open, + close_t *Close, + start_t *Start, + read_t *Read, + write_t *Write, + rewrite_t *Rewrite, + delete_t *Delete ) + : Open(Open) + , Close(Close) + , Start(Start) + , Read(Read) + , Write(Write) + , Rewrite(Rewrite) + , Delete(Delete) + {} + +#if FILE_IO_IMPLEMENTED + int read_next(); + int fildelete(); + void ioinit(); + void ioexit(); + int iofork(); + int iosync(); + int commit(); + int rollback(); + int iounlock(); + char * ioversion(); +#endif +}; + + +// Our implementation returns this populated structure + +gcobol_io_t* +gcobol_fileops() { + return new gcobol_io_t( __io__file_open, + __io__file_close, + __io__file_start, + __io__file_read, + __io__file_write, + __io__file_rewrite, + __io__file_delete ); +} + +/* + * To use this structure, whether our gcobolio.so or another, initialize with: + * + * gcobol_io_t * gfile = gcobol_filops(file); + * + * That means every gcobol binary expects to be linked to a library + * that supplies gcobol_fileops(). By default, we link to ours. + * + * Then, in libgcobol, replace direct calls with calls through fileops. + * That is, instead of + * + * __gg__file_open("foo", "r", false ); + * use + * gfile->Open("foo", "r", false ); + * + * You'll probably want some kind of trampoline to avoid the need to + * generate the Gimple to call through a pointer to a structure: + */ + +/* + * I/O via interface + */ +static gcobol_io_t * gcobol_io = NULL; + +static gcobol_io_t * +gcobol_io_funcs() { + if( ! gcobol_io ) + { + gcobol_io = gcobol_fileops(); + if( !gcobol_io ) + { + __gg__abort("gcobol_io_funcs(): gcobol_io is NULL"); + } + } + return gcobol_io; +} + +extern "C" +void +__gg__file_open(cblc_file_t *file, + char *filename, + int mode_char, + int is_quoted) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Open(file, filename, mode_char, is_quoted); + } + +extern "C" +void +__gg__file_close( cblc_file_t *file, int how ) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Close(file, how); + } + +extern "C" +void +__gg__file_start( cblc_file_t *file, + int relop, + int first_last_key, + size_t length) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Start(file, relop, first_last_key, length); + } + +extern "C" +void +__gg__file_read(cblc_file_t *file, + int where) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Read(file, where); + } + +extern "C" +void +__gg__file_write( cblc_file_t *file, + unsigned char *location, + size_t length, + int after, + int lines, + int is_random ) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Write(file, location, length, after, lines, is_random); + } + +extern "C" +void +__gg__file_rewrite(cblc_file_t *file, size_t length, bool is_random) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Rewrite(file, length, is_random); + } + +extern "C" +void +__gg__file_delete(cblc_file_t *file, bool is_random) + { + gcobol_io_t *functions = gcobol_io_funcs(); + functions->Delete(file, is_random); + } + +/* end interface functions */ + diff --git a/libgcobol/gfileio.h b/libgcobol/gfileio.h new file mode 100644 index 00000000000..e70d84fc91e --- /dev/null +++ b/libgcobol/gfileio.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef GFILEIO_H_ +#define GFILEIO_H_ + +extern "C" +{ +void __gg__handle_error(const char *function, const char *msg); + +void __gg__file_open( cblc_file_t *file, + char *filename, + int mode_char, + int is_quoted); + +void __gg__file_reopen(cblc_file_t *file, int mode_char); + +void __gg__file_close( cblc_file_t *file, int how ); + +void __gg__file_read( cblc_file_t *file, + int where); + +void __gg__file_write( cblc_file_t *file, + unsigned char *location, + size_t length, + int after, + int lines, + int is_random ); +} + +#endif \ No newline at end of file diff --git a/libgcobol/gmath.cc b/libgcobol/gmath.cc new file mode 100644 index 00000000000..2af0e8a8614 --- /dev/null +++ b/libgcobol/gmath.cc @@ -0,0 +1,2174 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "common-defs.h" +#include "io.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "common-defs.h" +#include "gmath.h" +#include "gcobolio.h" + +#include +#include +#include + +#ifdef __aarch64__ +#define __float128 _Float128 +#endif + +#define MAX_INTERMEDIATE_BITS 126 +#define MAX_INTERMEDIATE_DECIMALS 16 + +static int +conditional_stash( cblc_field_t *destination, + size_t destination_o, + size_t destination_s, + bool on_error_flag, + __int128 value, + int rdigits, + cbl_round_t rounded) + { + int retval = compute_error_none; + if( !on_error_flag ) + { + // It's an uncomplicated assignment, because there was no + // ON SIZE ERROR phrase + __gg__int128_to_qualified_field(destination, + destination_o, + destination_s, + value, + rdigits, + rounded, + &retval); + } + else + { + // This is slightly more complex, because in the event of a + // SIZE ERROR. we need to leave the original value untouched + + unsigned char *stash = (unsigned char *)malloc(destination_s); + memcpy(stash, destination->data+destination_o, destination_s); + + __gg__int128_to_qualified_field(destination, + destination_o, + destination_s, + value, + rdigits, + rounded, + &retval); + if( retval ) + { + // Because there was a size error, we will report that + // upon return, and we need to put back the original value: + memcpy(destination->data+destination_o, stash, destination_s); + } + free(stash); + } + return retval; + } + +static int +conditional_stash( cblc_field_t *destination, + size_t destination_o, + size_t destination_s, + bool on_error_flag, + _Float128 value, + cbl_round_t rounded) + { + int retval = compute_error_none; + if( !on_error_flag ) + { + // It's an uncomplicated assignment, because there was no + // ON SIZE ERROR phrase + __gg__float128_to_qualified_field(destination, + destination_o, + value, + rounded, + &retval); + } + else + { + // This is slightly more complex, because in the event of a + // SIZE ERROR. we need to leave the original value untouched + unsigned char *stash = (unsigned char *)malloc(destination_s); + memcpy(stash, destination->data+destination_o, destination_s); + __gg__float128_to_qualified_field(destination, + destination_o, + value, + rounded, + &retval); + if( retval ) + { + // Because there was a size error, we will report that + // upon return, and we need to put back the original value: + memcpy(destination->data+destination_o, stash, destination_s); + } + free(stash); + } + return retval; + } + + +#if defined(__aarch64__) +# define __float128 _Float128 /* double */ +#endif + +static +_Float128 +divide_helper_float(_Float128 a_value, + _Float128 b_value, + int *compute_error) + { + if( b_value == 0 ) + { + // Can't divide by zero + *compute_error |= compute_error_divide_by_zero; + return a_value; + } + + // Do the actual division, giving us 0.399999999999999999999999999999999971 + a_value /= b_value; + + if( __builtin_isinf(a_value) ) + { + *compute_error |= compute_error_overflow; + return 0; + } + + if( __builtin_isnan(a_value) ) + { + *compute_error |= compute_error_underflow; + return 0; + } + + return a_value; + } + +static +_Float128 +multiply_helper_float(_Float128 a_value, + _Float128 b_value, + int *compute_error) + { + a_value *= b_value; + + if( __builtin_isinf(a_value) ) + { + *compute_error |= compute_error_overflow; + return 0; + } + + if( __builtin_isnan(a_value) ) + { + *compute_error |= compute_error_underflow; + return 0; + } + + return a_value; + } + +static +_Float128 +addition_helper_float(_Float128 a_value, + _Float128 b_value, + int *compute_error) + { + a_value += b_value; + + if( __builtin_isinf(a_value) ) + { + *compute_error |= compute_error_overflow; + return 0; + } + + if( __builtin_isnan(a_value) ) + { + *compute_error |= compute_error_underflow; + return 0; + } + + return a_value; + } + +static +_Float128 +subtraction_helper_float(_Float128 a_value, + _Float128 b_value, + int *compute_error) + { + a_value -= b_value; + + if( __builtin_isinf(a_value) ) + { + *compute_error |= compute_error_overflow; + return 0; + } + + if( __builtin_isnan(a_value) ) + { + *compute_error |= compute_error_underflow; + return 0; + } + + return a_value; + } + +extern "C" +void +__gg__pow( cbl_arith_format_t, + size_t, + size_t, + size_t, + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + cblc_field_t **B = __gg__treeplet_2f; + size_t *B_o = __gg__treeplet_2o; + size_t *B_s = __gg__treeplet_2s; + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + _Float128 avalue = __gg__float128_from_qualified_field(A[0], A_o[0], A_s[0]); + _Float128 bvalue = __gg__float128_from_qualified_field(B[0], B_o[0], B_s[0]); + _Float128 tgt_value; + + if( avalue == 0 && bvalue == 0 ) + { + *compute_error |= compute_error_exp_zero_by_zero; + tgt_value = 1; + } + else if(avalue == 0 && bvalue < 0 ) + { + *compute_error |= compute_error_exp_zero_by_minus; + tgt_value = 0; + } + else + { + // Calculate our answer, in floating point: + errno = 0; + feclearexcept(FE_ALL_EXCEPT); + tgt_value = powf128(avalue, bvalue); + if( errno || fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) ) + { + // One of a large number of errors took place. See math_error(7) and + // pow(3). Let's just use this last error as a grab-bag; I didn't + // care to go down the rabbit hole of figuring out if a floating point + // number did or did not have a fractional part. That way lies + // madness. + *compute_error |= compute_error_exp_minus_by_frac; + // This kind of error doesn't overwrite the target, so the returned + // value is not relevant. Make it zero to avoid overheating the + // converstion routine + tgt_value = 0; + } + } + if( !(*compute_error & compute_error_exp_minus_by_frac) ) + { + *compute_error |= conditional_stash(C[0], + C_o[0], + C_s[0], + (on_error_flag & ON_SIZE_ERROR), + tgt_value, + *rounded); + } + } + +extern "C" +void +__gg__process_compute_error(int compute_error) + { + // This routine gets called after a series of parser_op operations is + // complete (see parser_assign()) when the source code didn't specify + // an ON SIZE ERROR clause. + if( compute_error & compute_error_divide_by_zero) + { + exception_raise(ec_size_zero_divide_e); + } + else if( compute_error & compute_error_truncate ) + { + exception_raise(ec_size_truncation_e); + } + else if( compute_error & ( compute_error_exp_zero_by_zero + | compute_error_exp_zero_by_minus + | compute_error_exp_minus_by_frac ) ) + { + exception_raise(ec_size_exponentiation_e); + } + else if( compute_error & compute_error_overflow ) + { + exception_raise(ec_size_overflow_e); + } + else if( compute_error & compute_error_underflow ) + { + exception_raise(ec_size_underflow_e); + } + } + +typedef unsigned __int128 uint128; +typedef struct int256 + { + union + { + unsigned char data[32]; + uint64_t i64 [4]; + uint128 i128[2]; + }; + }int256; + +static int +multiply_int256_by_int64(int256 &product, const uint64_t multiplier) + { + // Typical use of this routine is multiplying a temporary value by + // a factor of ten. This is effectively left-shifting by decimal + // digits. See scale_int256_by_digits + uint64_t overflows[5] = {}; + for(int i=0; i<4; i++) + { + uint128 temp = (uint128)product.i64[i] * multiplier; + product.i64[i] = *(uint64_t *)(&temp); + overflows[i+1] = *(uint64_t *)((uint8_t *)(&temp) + 8); + } + + for(int i=1; i<4; i++) + { + product.i64[i] += overflows[i]; + if(product.i64[i] < overflows[i]) + { + overflows[i+1] += 1; + } + } + // Indicate that an overflow took place. This is not useful unless the int256 + // is known to be positive. + return overflows[4]; + } + +static int +add_int256_to_int256(int256 &sum, const int256 addend) + { + uint128 overflows[3] = {}; + for(int i=0; i<2; i++) + { + sum.i128[i] += addend.i128[i]; + if( sum.i128[i] < addend.i128[i] ) + { + overflows[i+1] = 1; + } + } + if( overflows[1] ) + { + sum.i128[1] += overflows[1]; + if( sum.i128[1] == 0 ) + { + overflows[2] = 1; + } + } + // Indicate that an overflow took place. This is not useful unless the two + // values are known to be positive. + return (int)overflows[2]; + } + +static void +negate_int256(int256 &val) + { + val.i128[0] = ~val.i128[0]; + val.i128[1] = ~val.i128[1]; + val.i128[0] += 1; + if( !val.i128[0] ) + { + val.i128[1] += 1; + } + } + +static int +subtract_int256_from_int256(int256 &difference, int256 subtrahend) + { + negate_int256(subtrahend); + return add_int256_to_int256(difference, subtrahend); + } + +static void +scale_int256_by_digits(int256 &val, int digits) + { + uint64_t pot; + while(digits > 17) + { + pot = (uint64_t)__gg__power_of_ten(17); + multiply_int256_by_int64(val, pot); + digits -= 17; + } + pot = (uint64_t)__gg__power_of_ten(digits); + multiply_int256_by_int64(val, pot); + } + +static void +divide_int256_by_int64(int256 &val, uint64_t divisor) + { + // val needs to be a positive number + uint128 temp = 0; + for( int i=3; i>=0; i-- ) + { + // Left shift temp 64 bits: + *(uint64_t *)(((uint8_t *)&temp)+8) = *(uint64_t *)(((uint8_t *)&temp)+0); + + // Put the high digit of val into the bottom of temp + *(uint64_t *)(((uint8_t *)&temp)+0) = val.i64[i]; + + // Divide that combinary by divisor to get the new digits + val.i64[i] = temp / divisor; + + // And the new temp is that combination modulo divisor + temp = temp % divisor; + } + } + +static int +squeeze_int256(int256 &val, int &rdigits) + { + int overflow = 0; + // It has been decreed that at this juncture the result must fit into + // MAX_FIXED_POINT_DIGITS. If the result does not, we have an OVERFLOW error. + + int is_negative = val.data[31] & 0x80; + if( is_negative ) + { + negate_int256(val); + } + + // As long as there are some decimal places left, we hold our nose and right- + // shift a too-large value rightward by decimal digits. In other words, we + // truncate the fractional part to make room for the integer part: + while(rdigits > 0 && val.i128[1] ) + { + divide_int256_by_int64(val, 10UL); + rdigits -= 1; + } + + // At this point, to be useful, val has to have fewer than 128 bits: + if( val.i128[1] ) + { + overflow = compute_error_overflow; + } + else + { + // We know that it has fewer than 128 bits. But the remaining 128 bits need + // to be less than 10^MAX_FIXED_POINT_DIGITS. This gets a bit nasty here, + // since at this writing the gcc compiler doesn't understand 128-bit + // constants. So, we are forced into some annoying compiler gymnastics. +#if MAX_FIXED_POINT_DIGITS != 37 +#error MAX_FIXED_POINT_DIGITS needs to be 37 +#endif + + // These sixteen bytes comprise the binary value of 10^38 + static const uint8_t C1038[] = {0x00, 0x00, 0x00, 0x00, 0x40, 0x22, 0x8a, 0x09, + 0x7a, 0xc4, 0x86, 0x5a, 0xa8, 0x4c, 0x3b, 0x4b}; + static const uint128 biggest = *(uint128 *)C1038; + + // If we still have some rdigits to throw away, we can keep shrinking + // the value: + + while(rdigits > 0 && val.i128[0] >= biggest ) + { + divide_int256_by_int64(val, 10UL); + rdigits -= 1; + } + + // And we have to make sure that rdigits isn't too big + + while(rdigits > MAX_FIXED_POINT_DIGITS) + { + divide_int256_by_int64(val, 10UL); + rdigits -= 1; + } + + if( val.i128[0] >= biggest ) + { + overflow = compute_error_overflow; + } + } + + if( is_negative ) + { + negate_int256(val); + } + + return overflow; + } + +static void +get_int256_from_qualified_field(int256 &var, + int &rdigits, + cblc_field_t *field, + size_t field_o, + size_t field_s) + { + var.i128[0] = (uint128)__gg__binary_value_from_qualified_field( &rdigits, + field, + field_o, + field_s); + if( var.data[15] & 0x80 ) + { + // This value is negative, so extend the sign bit: + memset(var.data + 16, 0xFF, 16); + } + else + { + // This value is positive + memset(var.data + 16, 0x00, 16); + } + } + +static int256 phase1_result; +static int phase1_rdigits; + +static _Float128 phase1_result_float; + +extern "C" +void +__gg__add_fixed_phase1( cbl_arith_format_t , + size_t nA, + size_t , + size_t , + cbl_round_t *, + int , + int *compute_error + ) + { + // Our job is to add together the nA fixed-point values in the A[] array + + // The result goes into the temporary phase1_result. + + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + + // Let us prime the pump with the first value of A[] + get_int256_from_qualified_field(phase1_result, phase1_rdigits, A[0], A_o[0], A_s[0]); + + // We now go into a loop adding each of the A[] values to phase1_result: + + for( size_t i=1; i temp_rdigits ) + { + scale_int256_by_digits(temp, phase1_rdigits - temp_rdigits); + temp_rdigits = phase1_rdigits; + } + else if( phase1_rdigits < temp_rdigits ) + { + scale_int256_by_digits(phase1_result, temp_rdigits - phase1_rdigits); + phase1_rdigits = temp_rdigits; + } + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + add_int256_to_int256(phase1_result, temp); + } + + // phase1_result/phase1_rdigits now reflect the sum of all A[] + + int overflow = squeeze_int256(phase1_result, phase1_rdigits); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + } + +extern "C" +void +__gg__addf1_fixed_phase2( cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + // This is the assignment phase of an ADD Format 1 + + // We take phase1_result and accumulate it into C + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + + if( C[0]->type == FldFloat) + { + // The target we need to accumulate into is a floating-point number, so we + // need to convert our fixed-point intermediate into floating point and + // proceed accordingly. + + // Convert the intermediate + _Float128 value_a = (_Float128)phase1_result.i128[0]; + value_a /= __gg__power_of_ten(phase1_rdigits); + + // Pick up the target + _Float128 value_b = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + + value_a += value_b; + + // At this point, we assign running_sum to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + value_a, + *rounded++); + } + else + { + // We have a fixed-point intermediate, and we are accumulating intoi a + // fixed point target. + int256 value_a = phase1_result; + int rdigits_a = phase1_rdigits; + + int256 value_b = {}; + int rdigits_b; + + get_int256_from_qualified_field(value_b, rdigits_b, C[0], C_o[0], C_s[0]); + + // We have to scale the one with fewer rdigits to match the one with greater + // rdigits: + if( rdigits_a > rdigits_b ) + { + scale_int256_by_digits(value_b, rdigits_a - rdigits_b); + rdigits_b = rdigits_a; + } + else if( rdigits_a < rdigits_b ) + { + scale_int256_by_digits(value_a, rdigits_b - rdigits_a); + rdigits_a = rdigits_b; + } + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + add_int256_to_int256(value_a, value_b); + + int overflow = squeeze_int256(value_a, rdigits_a); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + + // At this point, we assign running_sum to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + value_a.i128[0], + rdigits_a, + *rounded++); + } + } + +extern "C" +void +__gg__fixed_phase2_assign_to_c( cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + // This is the assignment phase of an ADD Format 2 + + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + + // We take phase1_result and put it into C + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + + if( C[0]->type == FldFloat) + { + // The target we need to accumulate into is a floating-point number, so we + // need to convert our fixed-point intermediate into floating point and + // proceed accordingly. + + // Convert the intermediate + _Float128 value_a = (_Float128)phase1_result.i128[0]; + value_a /= __gg__power_of_ten(phase1_rdigits); + + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + value_a, + *rounded++); + } + else + { + // We have a fixed-point intermediate, and we are accumulating intoi a + // fixed point target. + int256 value_a = phase1_result; + int rdigits_a = phase1_rdigits; + + int overflow = squeeze_int256(value_a, rdigits_a); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + + // At this point, we assign that value to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + value_a.i128[0], + rdigits_a, + *rounded++); + } + } + +extern "C" +void +__gg__add_float_phase1( cbl_arith_format_t , + size_t nA, + size_t , + size_t , + cbl_round_t *, + int , + int *compute_error + ) + { + // Our job is to add together the nA floating-point values in the A[] array + + // The result goes into the temporary phase1_result_ffloat. + + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + + // Let us prime the pump with the first value of A[] + phase1_result_float = __gg__float128_from_qualified_field(A[0], A_o[0], A_s[0]); + + // We now go into a loop adding each of the A[] values to phase1_result_flt: + + for( size_t i=1; itype == FldFloat || C[i]->type == FldFloat ) + { + _Float128 value_a = __gg__float128_from_qualified_field(A[i], A_o[i], A_s[i]); + _Float128 value_b = __gg__float128_from_qualified_field(C[i], C_o[i], C_s[i]); + + value_a = addition_helper_float(value_a, value_b, compute_error); + + // At this point, we assign the sum to *C. + *compute_error |= conditional_stash(C[i], C_o[i], C_s[i], + on_size_error, + value_a, + *rounded++); + } + else + { + // We have are doing fixed-point arithmetic. + int256 value_a; + int rdigits_a; + + int256 value_b; + int rdigits_b; + + get_int256_from_qualified_field(value_a, rdigits_a, A[i], A_o[i], A_s[i]); + get_int256_from_qualified_field(value_b, rdigits_b, C[i], C_o[i], C_s[i]); + + // We have to scale the one with fewer rdigits to match the one with greater + // rdigits: + if( rdigits_a > rdigits_b ) + { + scale_int256_by_digits(value_b, rdigits_a - rdigits_b); + rdigits_b = rdigits_a; + } + else if( rdigits_a < rdigits_b ) + { + scale_int256_by_digits(value_a, rdigits_b - rdigits_a); + rdigits_a = rdigits_b; + } + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + add_int256_to_int256(value_a, value_b); + + int overflow = squeeze_int256(value_a, rdigits_a); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + + // At this point, we assign the sum to *C. + *compute_error |= conditional_stash(C[i], C_o[i], C_s[i], + on_size_error, + value_a.i128[0], + rdigits_a, + *rounded++); + } + } + } + +extern "C" +void +__gg__subtractf1_fixed_phase2(cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + // This is the assignment phase of an ADD Format 1 + + // We take phase1_result and subtrace it from C + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + + if( C[0]->type == FldFloat) + { + // The target we need to accumulate into is a floating-point number, so we + // need to convert our fixed-point intermediate into floating point and + // proceed accordingly. + + // Convert the intermediate + _Float128 value_a = (_Float128)phase1_result.i128[0]; + value_a /= __gg__power_of_ten(phase1_rdigits); + + // Pick up the target + _Float128 value_b = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + + value_b -= value_a; + + // At this point, we assign the difference to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + value_b, + *rounded++); + } + else + { + // We have a fixed-point intermediate, and we are accumulating intoi a + // fixed point target. + int256 value_a = phase1_result; + int rdigits_a = phase1_rdigits; + + int256 value_b = {}; + int rdigits_b; + + get_int256_from_qualified_field(value_b, rdigits_b, C[0], C_o[0], C_s[0]); + + // We have to scale the one with fewer rdigits to match the one with greater + // rdigits: + if( rdigits_a > rdigits_b ) + { + scale_int256_by_digits(value_b, rdigits_a - rdigits_b); + rdigits_b = rdigits_a; + } + else if( rdigits_a < rdigits_b ) + { + scale_int256_by_digits(value_a, rdigits_b - rdigits_a); + rdigits_a = rdigits_b; + } + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + subtract_int256_from_int256(value_b, value_a); + + int overflow = squeeze_int256(value_b, rdigits_b); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + + // At this point, we assign running_sum to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + value_b.i128[0], + rdigits_b, + *rounded++); + } + } + +extern "C" +void +__gg__subtractf2_fixed_phase1(cbl_arith_format_t , + size_t nA, + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + // This is the calculation phase of a fixed-point SUBTRACT Format 2 + + cblc_field_t **B = __gg__treeplet_2f; + size_t *B_o = __gg__treeplet_2o; + size_t *B_s = __gg__treeplet_2s; + + // Add up all the A values + __gg__add_fixed_phase1( not_expected_e , + nA, + 0, + 0, + rounded, + on_error_flag, + compute_error); + + // Subtract that from the B value: + + int256 value_a = phase1_result; + int rdigits_a = phase1_rdigits; + + int256 value_b = {}; + int rdigits_b; + + get_int256_from_qualified_field(value_b, rdigits_b, B[0], B_o[0], B_s[0]); + + // We have to scale the one with fewer rdigits to match the one with greater + // rdigits: + if( rdigits_a > rdigits_b ) + { + scale_int256_by_digits(value_b, rdigits_a - rdigits_b); + rdigits_b = rdigits_a; + } + else if( rdigits_a < rdigits_b ) + { + scale_int256_by_digits(value_a, rdigits_b - rdigits_a); + rdigits_a = rdigits_b; + } + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + subtract_int256_from_int256(value_b, value_a); + + int overflow = squeeze_int256(value_b, rdigits_b); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + phase1_result = value_b; + phase1_rdigits = rdigits_b; + } + + +extern "C" +void +__gg__subtractf1_float_phase2(cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + // This is the assignment phase of an ADD Format 2 + // We take phase1_result and subtract it from C + + _Float128 temp = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + temp = subtraction_helper_float(temp, phase1_result_float, compute_error); + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + temp, + *rounded++); + } + + +extern "C" +void +__gg__subtractf2_float_phase1(cbl_arith_format_t , + size_t nA, + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + // This is the calculation phase of a fixed-point SUBTRACT Format 2 + + cblc_field_t **B = __gg__treeplet_2f; + size_t *B_o = __gg__treeplet_2o; + size_t *B_s = __gg__treeplet_2s; + + // Add up all the A values + __gg__add_float_phase1( not_expected_e , + nA, + 0, + 0, + rounded, + on_error_flag, + compute_error + ); + + // Subtract that from the B value: + _Float128 value_b = __gg__float128_from_qualified_field(B[0], B_o[0], B_s[0]); + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + phase1_result_float = subtraction_helper_float(value_b, phase1_result_float, compute_error); + } + +extern "C" +void +__gg__subtractf3( cbl_arith_format_t , + size_t nA, + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + // This is an ADD Format 3. Each A[i] gets accumulated into each C[i]. Each + // SUBTRACTION is treated separately. + + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + + for(size_t i=0; itype == FldFloat || C[i]->type == FldFloat) + { + _Float128 value_a = __gg__float128_from_qualified_field(A[i], A_o[i], A_s[i]); + _Float128 value_b = __gg__float128_from_qualified_field(C[i], C_o[i], C_s[i]); + + value_b = subtraction_helper_float(value_b, value_a, compute_error); + + // At this point, we assign the sum to *C. + *compute_error |= conditional_stash(C[i], C_o[i], C_s[i], + on_size_error, + value_b, + *rounded++); + } + else + { + // We are doing fixed-point subtraction. + int256 value_a; + int rdigits_a; + + int256 value_b; + int rdigits_b; + + get_int256_from_qualified_field(value_a, rdigits_a, A[i], A_o[i], A_s[i]); + get_int256_from_qualified_field(value_b, rdigits_b, C[i], C_o[i], C_s[i]); + + // We have to scale the one with fewer rdigits to match the one with greater + // rdigits: + if( rdigits_a > rdigits_b ) + { + scale_int256_by_digits(value_b, rdigits_a - rdigits_b); + rdigits_b = rdigits_a; + } + else if( rdigits_a < rdigits_b ) + { + scale_int256_by_digits(value_a, rdigits_b - rdigits_a); + rdigits_a = rdigits_b; + } + + // The two numbers have the same number of rdigits. It's now safe to add + // them. + subtract_int256_from_int256(value_b, value_a); + + int overflow = squeeze_int256(value_b, rdigits_b); + + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + + // At this point, we assign the sum to *C. + *compute_error |= conditional_stash(C[i], C_o[i], C_s[i], + on_size_error, + value_b.i128[0], + rdigits_b, + *rounded++); + } + } + } + +static bool multiply_intermediate_is_float; +static _Float128 multiply_intermediate_float; +static __int128 multiply_intermediate_int128; +static int multiply_intermediate_rdigits; + +extern "C" +void +__gg__multiplyf1_phase1(cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *, + int , + int *) + { + // We are getting just the one value, which we are converting to the necessary + // intermediate form + + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + + if( A[0]->type == FldFloat ) + { + multiply_intermediate_is_float = true; + multiply_intermediate_float = __gg__float128_from_qualified_field(A[0], + A_o[0], + A_s[0]); + } + else + { + multiply_intermediate_is_float = false; + multiply_intermediate_int128 = + __gg__binary_value_from_qualified_field(&multiply_intermediate_rdigits, + A[0], + A_o[0], + A_s[0]); + } + } + +static +void multiply_int128_by_int128(int256 &ABCD, + __int128 ab_value, + __int128 cd_value) + { + int is_negative = ( ((uint8_t *)(&ab_value))[15]^((uint8_t *)(&cd_value))[15]) & 0x80; + if( ab_value < 0 ) + { + ab_value = -ab_value; + } + if( cd_value < 0 ) + { + cd_value = -cd_value; + } + + uint128 AC00; + uint128 AD0; + uint128 BC0; + uint128 BD; + + // Let's extract the digits. + uint64_t a = *(uint64_t *)((unsigned char *)(&ab_value)+8); + uint64_t b = *(uint64_t *)((unsigned char *)(&ab_value)+0); + uint64_t c = *(uint64_t *)((unsigned char *)(&cd_value)+8); + uint64_t d = *(uint64_t *)((unsigned char *)(&cd_value)+0); + + // multiply (a0 + b) * (c0 + d) + + AC00 = (uint128)a * c; + AD0 = (uint128)a * d; + BC0 = (uint128)b * c; + BD = (uint128)b * d; + + // ABCD is the sum of those four pieces + int256 temp; + + ABCD.i128[1] = 0; + ABCD.i128[0] = BD; + + temp.i64[3] = 0; + memcpy(&temp.i64[1], &BC0, 16); + temp.i64[0] = 0; + add_int256_to_int256(ABCD, temp); + + memcpy(&temp.i64[1], &AD0, 16); + add_int256_to_int256(ABCD, temp); + + temp.i64[1] = 0; + memcpy(&temp.i64[2], &AC00, 16); + add_int256_to_int256(ABCD, temp); + + // ABCD is now a 256-bit integer with rdigits decimal places + if(is_negative) + { + negate_int256(ABCD); + } + } + + +extern "C" +void +__gg__multiplyf1_phase2(cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + int error_this_time=0; + + _Float128 a_value; + _Float128 b_value; + + if( multiply_intermediate_is_float ) + { + a_value = multiply_intermediate_float; + if( C[0]->type == FldFloat ) + { + b_value = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + goto float_float; + } + else + { + // float times fixed + b_value = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + goto float_float; + } + } + else + { + if( C[0]->type == FldFloat ) + { + // gixed * float + a_value = (_Float128) multiply_intermediate_int128; + if( multiply_intermediate_rdigits ) + { + a_value /= (_Float128)__gg__power_of_ten(multiply_intermediate_rdigits); + } + b_value = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + goto float_float; + } + else + { + // fixed times fixed + + // We have two 128-bit numbers. Call them AB and CD, where A, B, C, D are + // 64-bit "digits". We need to multiply them to create a 256-bit result + + int cd_rdigits; + __int128 ab_value = multiply_intermediate_int128; + __int128 cd_value = __gg__binary_value_from_qualified_field(&cd_rdigits, C[0], C_o[0], C_s[0]); + + int256 ABCD; + int rdigits = multiply_intermediate_rdigits + cd_rdigits; + + multiply_int128_by_int128(ABCD, ab_value, cd_value); + + int overflow = squeeze_int256(ABCD, rdigits); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + // At this point, we assign running_sum to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + ABCD.i128[0], + rdigits, + *rounded++); + + goto done; + } + } + float_float: + + a_value = multiply_helper_float(a_value, b_value, &error_this_time); + + if( error_this_time && on_size_error) + { + *compute_error |= error_this_time; + rounded++; + } + else + { + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + a_value, + *rounded++); + } + done: + return; + } + +extern "C" +void +__gg__multiplyf2( cbl_arith_format_t , + size_t , + size_t , + size_t nC, + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + cblc_field_t **B = __gg__treeplet_2f; + size_t *B_o = __gg__treeplet_2o; + size_t *B_s = __gg__treeplet_2s; + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + + bool got_float = false; + _Float128 product_float; + int256 product_fix; + int product_fix_digits; + + if( A[0]->type == FldFloat || B[0]->type == FldFloat ) + { + _Float128 a_value = __gg__float128_from_qualified_field(A[0], A_o[0], A_s[0]); + _Float128 b_value = __gg__float128_from_qualified_field(B[0], B_o[0], B_s[0]); + product_float = multiply_helper_float(a_value, b_value, compute_error); + got_float = true; + } + else + { + int a_rdigits; + int b_rdigits; + __int128 a_value = __gg__binary_value_from_qualified_field(&a_rdigits, A[0], A_o[0], A_s[0]); + __int128 b_value = __gg__binary_value_from_qualified_field(&b_rdigits, B[0], B_o[0], B_s[0]); + product_fix_digits = a_rdigits + b_rdigits; + multiply_int128_by_int128(product_fix, a_value, b_value); + int overflow = squeeze_int256(product_fix, product_fix_digits); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + } + + for(size_t i=0; i> (128 - bits); + as128[i] <<= bits; + as128[i] += overflow; + overflow = temp; + } + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +static char * +int256_as_decimal(int256 val) + { + char ach[120]; + memset(ach, 0, sizeof(ach)); + strcpy(ach, "0"); + int index = 0; + while(val.i128[0] || val.i128[1]) + { + int256 before; + int256 after; + before = val; + after = val; + divide_int256_by_int64(after, 10); + multiply_int256_by_int64(after, 10); + uint64_t digit = before.i64[0] - after.i64[0]; + ach[index++] = digit + '0'; + divide_int256_by_int64(val, 10); + } + if( !index ) + { + index = 1; + } + index -= 1; + int r = 0; + static char retval[120]; + while(index >= 0) + { + retval[r++] = ach[index--]; + } + retval[r++] = '\0'; + return retval; + } +#pragma GCC diagnostic pop + + +static void +divide_int128_by_int128(int256 "ient, + int "ient_rdigits, + __int128 dividend, + int dividend_rdigits, + __int128 divisor, + int divisor_rdigits, + int *compute_error) + { + if( divisor == 0 ) + { + *compute_error |= compute_error_divide_by_zero; + memset("ient, 0, sizeof(quotient)); + memcpy("ient, ÷nd, 8); + quotient_rdigits = dividend_rdigits; + return; + } + + bool is_negative = false; + if(dividend < 0) + { + is_negative = !is_negative; + dividend = -dividend; + } + if(divisor < 0) + { + is_negative = !is_negative; + divisor = -divisor; + } + + // We are going to be referencing the 64-bit pices of the 128-bit divisor: + uint64_t *divisor64 = (uint64_t *)&divisor; + + quotient.i128[1] = 0; + quotient.i128[0] = dividend; + + // In order to get 0.3333333.... from 1 / 3, we are going to scale up the + // numerator so that it has 37 rdigits: + + int scale = MAX_FIXED_POINT_DIGITS; + scale_int256_by_digits(quotient, scale); + quotient_rdigits = scale + dividend_rdigits - divisor_rdigits; + + // Now, let's see if we can do a simple divide-by-single-place calculation: + + if( divisor64[1] == 0 ) + { + // Yes! The divisor fits into 64 bits: + divide_int256_by_int64(quotient, (uint64_t)divisor); + } + else + { + // We have to do long division, and that means Knuth's Algorithm D. Let's + // review where we are. + // + // We are using 64-bit places to divide one 128-bit number by another. We + // know that both are positive. So, we are dividing + // + // AB by CD, where we know C is non-zero. + // + // Because we want fractional digits to the right, we multiplied by 10**37, + // which is smaller than 2**64, so we have one additional place: + // + // ABx by CD + // + // Algorithm D requires that we left-shift ABX and CD by enough bits to make + // turn on high-order by of CD. This will be a value between 1 and 63 + // shifts, resulting in + // + // ABxy by CD. + // + // We can know that the quotient will have at most two places. We can see + // this in the decimal analogy. The worst case scenario is dividing + // + // 99 by 10 + // + // We multiply the top by 10 to give us one fractional decimal place in the + // result: + // + // 990 by 10 + // + // To satisfy Algorithm D's requirement that C be >= b/2, we multiply both + // dividend and divisor by 5: + // + // 4950 by 50 + // + // And then we do the work that gives us the two-place answer of 99. + // + // + // Here is our four-place 256-bit "numerator" + int256 numerator; + + // Copy the three-place ABx value into the numerator area + memcpy(&numerator, "ient, sizeof(quotient)); + + // Calculate how many bits we need to shift CD to make the high-order bit + // turn on: + + int bits_to_shift = 0; + int i=15; + while( ((uint8_t *)(&divisor))[i] == 0 ) + { + i -= 1; + bits_to_shift += 8; + } + uint8_t tail = ((uint8_t *)(&divisor))[i]; + while( !(tail & 0x80) ) + { + bits_to_shift += 1; + tail <<= 1; + } + + // Shift both the numerator and the divisor that number of bits + + shift_in_place128((uint8_t *)&numerator, sizeof(numerator), bits_to_shift); + shift_in_place128((uint8_t *)&divisor, sizeof(divisor), bits_to_shift); + + + // We are now ready to do the guess-multiply-subtract loop. We know that + // the result will have two places, so we know we are going to go through + // that loop two times. We will build the quotient from the high-order + // place down: + + // Let's prime the pump by loading remnant with the A value of ABxyz + int q_place = 1; + + memset("ient, 0, sizeof(quotient)); + + while( q_place >= 0 ) + { + // We develop our guess for a quotient by dividing the top two places of + // the numerator area by C + uint128 temp; + uint64_t *temp64 = (uint64_t *)&temp; + + temp64[1] = numerator.i64[q_place+2]; + temp64[0] = numerator.i64[q_place+1]; + + quotient.i64[q_place] = temp / divisor64[1]; + + // Now we multiply our 64-bit guess by the 128-bit CD to get the + // three-place value we are going to subtract from the numerator area. + + uint64_t subber[3]; + subber[2] = 0; + + // Start with the bottom 128 bits of the "subber" + *(uint128 *)subber = (uint128) divisor64[0] * quotient.i64[q_place]; + + // Get the next 128 bits of subber + temp = (uint128) divisor64[1] * quotient.i64[q_place]; + + // Add the top of the first product to the bottom of the second: + subber[1] += temp64[0]; + + // See if there was an overflow: + if( subber[1] < temp64[0] ) + { + // There was an overflow + subber[2] = 1; + } + // And now put the top of the second product into place: + subber[2] += temp64[1]; + + // "subber" is now the three-place product of the two-place divisor times + // the one-place guess + + // We now subtract the three-place subber from the appropriate place of + // the numerator: + + uint64_t borrow = 0; + for(size_t i=0; i<3; i++) + { + if( numerator.i64[q_place + i] == 0 && borrow ) + { + // We are subtracting from zero and we have a borrow. Leave the + // borrow on and just do the subtraction: + numerator.i64[q_place + i] -= subber[i]; + } + else + { + uint64_t stash = numerator.i64[q_place + i]; + numerator.i64[q_place + i] -= borrow; + numerator.i64[q_place + i] -= subber[i]; + if( numerator.i64[q_place + i] > stash ) + { + // After subtracting, the value got bigger, which means we have + // to borrow from the next value to the left + borrow = 1; + } + else + { + borrow = 0; + } + } + } + // The three-place subber has been removed from the numerator. + + // Now Algorithm D comes back into play. Knuth has proved that the guess + // is usually correct, but sometimes can be one too large, which means + // that the numerator area goes negative. On rare occasions, the guess can + // be two too large. So, we have to make sure that the numerator area is + // actually positive by adding subber back in. + + while( numerator.i64[q_place+2] & 0x8000000000000000UL ) + { + // We need to add subber back into the numerator area + uint64_t carry = 0; + for(size_t i=0; i<3; i++) + { + if( numerator.i64[q_place + i] == 0xFFFFFFFFFFFFFFFFUL && carry ) + { + // We are at the top and have a carry. Just leave the carry on + // and do the addition: + numerator.i64[q_place + i] += subber[i]; + } + else + { + // We are not at the top. + uint64_t stash = numerator.i64[q_place + i]; + numerator.i64[q_place + i] += carry; + numerator.i64[q_place + i] += subber[i]; + if( numerator.i64[q_place + i] < stash ) + { + // The addition caused the result to get smaller, meaning that + // we wrapped around: + carry = 1; + } + else + { + carry = 0; + } + } + } + } + q_place -= 1; + } + } + if( is_negative ) + { + negate_int256(quotient); + } + } + +extern "C" +void +__gg__dividef1_phase2(cbl_arith_format_t , + size_t , + size_t , + size_t , + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + int error_this_time=0; + + _Float128 a_value; + _Float128 b_value; + + if( multiply_intermediate_is_float ) + { + a_value = multiply_intermediate_float; + if( C[0]->type == FldFloat ) + { + b_value = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + goto float_float; + } + else + { + // float times fixed + b_value = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + goto float_float; + } + } + else + { + if( C[0]->type == FldFloat ) + { + // gixed * float + a_value = (_Float128) multiply_intermediate_int128; + if( multiply_intermediate_rdigits ) + { + a_value /= (_Float128)__gg__power_of_ten(multiply_intermediate_rdigits); + } + b_value = __gg__float128_from_qualified_field(C[0], C_o[0], C_s[0]); + goto float_float; + } + else + { + // fixed times fixed + + // We have two 128-bit numbers. Call them AB and CD, where A, B, C, D are + // 64-bit "digits". We need to multiply them to create a 256-bit result + + int dividend_rdigits; + __int128 dividend = __gg__binary_value_from_qualified_field(÷nd_rdigits, C[0], C_o[0], C_s[0]); + + int quotient_rdigits; + int256 quotient; + + divide_int128_by_int128(quotient, + quotient_rdigits, + dividend, + dividend_rdigits, + multiply_intermediate_int128, + multiply_intermediate_rdigits, + compute_error); + + int overflow = squeeze_int256(quotient, quotient_rdigits); + if( overflow ) + { + *compute_error |= compute_error_overflow; + } + // At this point, we assign the quotient to *C. + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + quotient.i128[0], + quotient_rdigits, + *rounded++); + + goto done; + } + } + float_float: + + b_value = divide_helper_float(b_value, a_value, &error_this_time); + + *compute_error |= error_this_time; + + if( error_this_time && on_size_error) + { + rounded++; + } + else + { + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + b_value, + *rounded++); + } + done: + return; + } + +extern "C" +void +__gg__dividef23(cbl_arith_format_t , + size_t , + size_t , + size_t nC, + cbl_round_t *rounded, + int on_error_flag, + int *compute_error + ) + { + cblc_field_t **A = __gg__treeplet_1f; + size_t *A_o = __gg__treeplet_1o; + size_t *A_s = __gg__treeplet_1s; + cblc_field_t **B = __gg__treeplet_2f; + size_t *B_o = __gg__treeplet_2o; + size_t *B_s = __gg__treeplet_2s; + cblc_field_t **C = __gg__treeplet_3f; + size_t *C_o = __gg__treeplet_3o; + size_t *C_s = __gg__treeplet_3s; + + bool on_size_error = !!(on_error_flag & ON_SIZE_ERROR); + int error_this_time=0; + + if( A[0]->type == FldFloat || B[0]->type == FldFloat ) + { + _Float128 a_value; + _Float128 b_value; + _Float128 c_value; + a_value = __gg__float128_from_qualified_field(A[0], A_o[0], A_s[0]); + b_value = __gg__float128_from_qualified_field(B[0], B_o[0], B_s[0]); + c_value = divide_helper_float(a_value, b_value, &error_this_time); + + *compute_error |= error_this_time; + if( !error_this_time ) + { + for(size_t i=0; itype == FldFloat || B[0]->type == FldFloat ) + { + _Float128 a_value; + _Float128 b_value; + _Float128 c_value; + a_value = __gg__float128_from_qualified_field(A[0], A_o[0], A_s[0]); + b_value = __gg__float128_from_qualified_field(B[0], B_o[0], B_s[0]); + c_value = divide_helper_float(a_value, b_value, &error_this_time); + + *compute_error |= error_this_time; + + if( !error_this_time ) + { + *compute_error |= conditional_stash(C[1], C_o[1], C_s[1], + on_size_error, + c_value, + *rounded_p++); + // This is floating point, and there is a remainder, and we don't know + // what that means. Set the remainder to zero + if( !*compute_error ) + { + c_value = 0; + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + c_value, + *rounded_p++); + } + } + } + else + { + // fixed divided by fixed + int dividend_rdigits; + __int128 dividend = __gg__binary_value_from_qualified_field(÷nd_rdigits, A[0], A_o[0], A_s[0]); + + int divisor_rdigits; + __int128 divisor = __gg__binary_value_from_qualified_field(&divisor_rdigits, B[0], B_o[0], B_s[0]); + + int quotient_rdigits; + int256 quotient; + + divide_int128_by_int128(quotient, + quotient_rdigits, + dividend, + dividend_rdigits, + divisor, + divisor_rdigits, + compute_error); + + *compute_error |= squeeze_int256(quotient, quotient_rdigits); + if( !*compute_error ) + { + // We are going to need the unrounded quotient to calculate the remainder + __int128 unrounded_quotient = 0; + int unrounded_quotient_digits; + rounded_p += 1;// Skip the rounded value for the remainder + cbl_round_t rounded = *rounded_p; + switch(rounded) + { + case truncation_e: + { + *compute_error |= conditional_stash(C[1], C_o[1], C_s[1], + on_size_error, + quotient.i128[0], + quotient_rdigits, + *rounded_p++); + unrounded_quotient = __gg__binary_value_from_qualified_field( + &unrounded_quotient_digits, + C[1], C_o[1], C_s[1]); + break; + } + default: + { + conditional_stash(C[1], C_o[1], C_s[1], + false, + quotient.i128[0], + quotient_rdigits, + truncation_e); + unrounded_quotient = __gg__binary_value_from_qualified_field( + &unrounded_quotient_digits, + C[1], C_o[1], C_s[1]); + // At this point, we assign the rounded quotient to *C. + *compute_error |= conditional_stash(C[1], C_o[1], C_s[1], + on_size_error, + quotient.i128[0], + quotient_rdigits, + *rounded_p++); + break; + } + } + if( !*compute_error ) + { + // We need to calculate the remainder + + // Remainders in COBOL are seriously weird. The NIST suite + // has an example where 174 is divided by 16. The quotient + // is a 999.9, and the remainder is a 9999 + + // So, here goes: 174 by 16 is 10.875. The unrounded + // assignment to Q is thus 10.8 + // You then multiply 10.8 by 16, giving 172.8 + // That gets subtracted from 174, giving 1.2 + // That gets assigned to the 9999 remainder, which is + // thus 1 + + // Any mathematician would walk away, slowly, shaking their head. + + // We need to multiply the unrounded quotient by the divisor. + int256 temp; + int temp_rdigits; + // Step 1: Multiply the unrounded quotient by the divisor + multiply_int128_by_int128(temp, unrounded_quotient, divisor); + temp_rdigits = unrounded_quotient_digits + divisor_rdigits; + + int256 odividend = {}; + memcpy(&odividend, ÷nd, sizeof(dividend)); + + // We need to line up the rdigits so that we can subtract temp from + // odividend: + + if( temp_rdigits < dividend_rdigits ) + { + scale_int256_by_digits(temp, dividend_rdigits-temp_rdigits); + temp_rdigits = dividend_rdigits; + } + else if(temp_rdigits > dividend_rdigits) + { + scale_int256_by_digits(odividend, temp_rdigits-dividend_rdigits); + } + + subtract_int256_from_int256(odividend, temp); + + *compute_error |= squeeze_int256(odividend, temp_rdigits); + + if( !*compute_error ) + { + *compute_error |= conditional_stash(C[0], C_o[0], C_s[0], + on_size_error, + odividend.i128[0], + temp_rdigits, + truncation_e); + } + } + } + } + } + diff --git a/libgcobol/gmath.h b/libgcobol/gmath.h new file mode 100644 index 00000000000..9aa8f635f4a --- /dev/null +++ b/libgcobol/gmath.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef GMATH_H_ +#define GMATH_H_ + +extern "C" +{ + +} + +#endif \ No newline at end of file diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc new file mode 100644 index 00000000000..e3d255a29d6 --- /dev/null +++ b/libgcobol/intrinsic.cc @@ -0,0 +1,5452 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Operational note for COBOL intrinsic functions: + + In general, the parameters to these functions are cblc_field_t pointers + along with an offset, size, and for some functions the "allflags", which + indicate that the variable is a table that was referenced as TABL(ALL) + + + */ + +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "common-defs.h" +#include "io.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "charmaps.h" + +#pragma GCC diagnostic ignored "-Wformat-truncation" + +#define JD_OF_1601_01_02 2305812.5 + +#define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0Q) +#define NO_RDIGITS (0) + +struct cobol_tm + { + int YYYY; // 1601-9999 + int MM; // 01-12 + int DD; // 01-28,29,30,31 + int hh; // 00-23 + int mm; // 00-59 + int ss; // 00-59 + int nanoseconds; // 0 through 999,999,999 + int tz_offset; // +/- 1359 + int week_of_year; // 01 - 52,53 + int day_of_year; // 001-365, 366 + int day_of_week; // 0-6; 0 being Monday + int days_in_year; // 365,366 + int weeks_in_year; // 52,53 + int ZZZZ; // Alternate year, when Jan 4 is Mon, Tue, or Wednesday + }; + +static int is_leap_year(int); + +typedef char * PCHAR; + +static void +trim_trailing_spaces(PCHAR left, PCHAR &right) + { + while( right > left ) + { + if( *(right-1) != internal_space ) + { + break; + } + right -= 1; + } + } + +static bool +is_zulu_format(PCHAR left, PCHAR &right) + { + bool retval = false; + if( right > left ) + { + retval = toupper(*(right-1)) == internal_Z; + } + return retval; + } + +static double +YMD_to_JD(int Y, int M, int D) + { + // Calculates the Julian Day + + if( M <= 2 ) + { + Y -= 1 ; + M += 12; + } + double A = floor(Y/100.); + double B = 2. - A + floor(A/4.); + + double JD; + JD = floor(365.25 * double(Y + 4716) + floor((30.6001 * double(M+1)))) + D + B -1524.5 ; + + return JD; + } + +static void +JD_to_YMD(int &YY, int &MM, int &DD, double JD) + { + JD += 0.5; + double Z = floor(JD); + double F = JD - Z; + double A; + if( Z < 2299161.0 ) + { + A = Z; + } + else + { + double alpha = floor( (Z-1867216.25) / 36524.25 ) ; + A = Z + 1.0 + alpha - floor(alpha/4.0); + } + double B = A + 1524; + double C = floor( (B - 122.1)/365.25 ); + double D = floor( 365.25 * C ); + double E = floor( (B-D)/30.6001 ); + + DD = (int)( B - D - floor(30.6001 * E) + F ); + MM = (int)( E < 14 ? E - 1 : E - 13 ); + YY = (int)( MM > 2 ? C - 4716 : C - 4715 ); + } + +static int +JD_to_DOW(double JD) + { + // Converts a Julian Day to 0 through 6, where + // 0 is Monday. + // 2415020.50000 is noon on 1900-01-01, which was a Monday + return ((int)(JD-0.5)+1)%7; + } + +#define DATE_STRING_BUFFER_SIZE 23 + +static +char * +timespec_to_string(char *retval, struct timespec &tp) + { + /* + Returns a 21-character string: + + 1 - 4 Four numeric digits of the year in the Gregorian calendar + 5 - 6 Two numeric digits of the month of the year, in the range 01 through 12 + 7 - 8 Two numeric digits of the day of the month, in the range 01 through 31 + 9 - 10 Two numeric digits of the hours past midnight, in the range 00 through 23 + 11 - 12 Two numeric digits of the minutes past the hour, in the range 00 through 59 + 13 - 14 Two numeric digits of the seconds past the minute, in the range 00 through 59 + 15 - 16 Two numeric digits of the hundredths of a second past the second, in the range + 17 Either the character '-' or the character '+'. + 18 - 19 If character position 17 is '-', two numeric digits are returned in the range 00 + through 12 indicating the number of hours that the reported time is behind + Greenwich mean time. + + If character position 17 is '+', two numeric digits are + returned in the range 00 through 13 indicating the number of hours that the + reported time is ahead of Greenwich mean time. If character position 17 is '0', the + value 00 is returned. + 20 - 21 Two numeric digits are returned in the range 00 through 59 indicating the number + of additional minutes that the reported time is ahead of or behind Greenwich + mean time, depending on whether character position 17 + */ + + const int size_of_buffer = DATE_STRING_BUFFER_SIZE; + const int offset_to_hundredths = 14; + const long nanoseconds_to_hundredths = 10000000; + + // Convert the nanosecond fraction to hundredths of a second: + char achCentiseconds[3]; + snprintf(achCentiseconds, 3, "%2.2ld", (tp.tv_nsec/nanoseconds_to_hundredths) ); + + // Convert the epoch seconds to broken-down time: + struct tm tm = {}; + + if( false ) + { + // With a forced date/time, eliminate local influences + gmtime_r(&tp.tv_sec, &tm); + } + else + { + localtime_r(&tp.tv_sec, &tm); + } + + // Format the time as per COBOL specifications, leaving two spaces for the + // hundredths of seconds: + strftime(retval, size_of_buffer, "%Y%m%d%H%M%S %z", &tm); + + // Copy the 100ths into place: + memcpy(retval+offset_to_hundredths, achCentiseconds, 2); + + return retval; + } + +static +void +string_to_dest(cblc_field_t *dest, const char *psz) + { + size_t dest_length = dest->capacity; + size_t source_length = strlen(psz); + size_t length = std::min(dest_length, source_length); + memset(dest->data, internal_space, dest_length); + memcpy(dest->data, psz, length); + } + +struct input_state + { + size_t nsubscript; + bool *subscript_alls; + size_t *subscripts; + size_t *subscript_limits; + bool done; + + void allocate(size_t N) + { + nsubscript = N; + if(N) + { + subscript_alls = (bool *) malloc(nsubscript); + subscripts = (size_t *)malloc(nsubscript); + subscript_limits = (size_t *)malloc(nsubscript); + } + done = false; + } + void deallocate() + { + if(nsubscript) + { + free(subscript_alls); + free(subscripts); + free(subscript_limits); + } + } + }; + +struct refer_state_for_all + { + size_t nflags; + size_t coefficients [MAXIMUM_TABLE_DIMENSIONS]; + size_t capacities [MAXIMUM_TABLE_DIMENSIONS]; + size_t limits [MAXIMUM_TABLE_DIMENSIONS]; + }; + +static +void +build_refer_state_for_all( refer_state_for_all &state, + cblc_field_t *field, + int flags) + { + memset(&state, 0, sizeof(refer_state_for_all) ); + if( flags & REFER_T_ALL_FLAGS_MASK ) + { + // At this point, refer points to the very first element of + // an array specification that includes at least one ALL subscript. At + // this time, those ALLs were calculated as if they had been replaced + // with one. + + // We are going to walk the reference up to its ultimate parent, picking + // up what we need along the way. + + size_t current_bit = 1; + size_t current_index = 0; + cblc_field_t *current_sizer = field; + while( current_sizer ) + { + while( current_sizer && !current_sizer->occurs_upper ) + { + // current_sizer isn't a table, which isn't unusual. + current_sizer = current_sizer->parent; + } + + if( !current_sizer ) + { + // We have found all of the elements in this data description + // that have OCCURS clauses + break; + } + + // We are sitting on an occurs clause: + + if( current_bit & flags ) + { + // It is an ALL subscript: + state.nflags += 1; + state.coefficients[current_index] = 1; + state.capacities[current_index] = current_sizer->capacity; + state.limits[current_index] = current_sizer->occurs_upper; + current_index += 1 ; + } + + current_bit <<= 1; + current_sizer = current_sizer->parent; + } + } + } + +static +bool +update_refer_state_for_all( refer_state_for_all &state, + cblc_field_t *field) + { + bool retval = false; // Means there is nothing left + + for(size_t i=0; idata += state.capacities[i]; + if( state.coefficients[i] <= state.limits[i] ) + { + // This coefficient is within range: + retval = true; + break; + } + + // We have used up this coefficient. + + // Remove the effects of incrementing this coefficient: + field->data -= state.limits[i] * state.capacities[i]; + // Reset the coefficient back to one: + state.coefficients[i] = 1; + + // And continue on to the next coefficient. + } + + return retval; + } + +static +int +year_to_yyyy(int arg1, int arg2, int arg3) + { + // See ISO/IEC 2014-1989 section 15.93 for a detailed description of the + // sliding window calculation + int max_year = arg2 + arg3; + int retval; + if( max_year % 100 >= arg1 ) + { + retval = arg1 + 100 * (max_year/100); + } + else + { + retval = arg1 + 100 * (max_year/100 - 1); + } + return retval; + } + +static +double +get_value_as_double_from_qualified_field( cblc_field_t *input, + size_t input_o, + size_t input_s) + { + double retval; + int rdigits; + + switch( input->type ) + { + case FldFloat: + fprintf(stderr, "get_value_as_double_from_qualified_field(): Hey!" + " We got an unexpected float in intrinsic.cc!\n"); + exit(1); + break; + + default: + retval = __gg__binary_value_from_qualified_field(&rdigits, + input, + input_o, + input_s); + for(int i=0; i= 0 ) + { + int week_of_year = adjusted_days/7 + 1; + if(week_of_year > ctm.weeks_in_year) + { + ctm.ZZZZ = ctm.YYYY+1; + ctm.week_of_year = 1; + } + else + { + ctm.ZZZZ = ctm.YYYY; + ctm.week_of_year = week_of_year; + } + } + else + { + ctm.ZZZZ = ctm.YYYY - 1; + ctm.week_of_year = weeks_in_year(ctm.ZZZZ); + } + } + +static +void +populate_ctm_from_JD(struct cobol_tm &ctm, double JD ) + { + // Extract the year, month, and day + int Y; + int M; + int D; + JD += JD_OF_1601_01_02; + JD_to_YMD(Y, M, D, JD); + + struct tm tm = {}; + tm.tm_mday = D; + tm.tm_mon = M-1; + tm.tm_year = Y-1900; + populate_ctm_from_tm(ctm, tm); + } + +static +void +populate_ctm_from_date( struct cobol_tm &ctm, + cblc_field_t *pdate, + size_t pdate_offset, + size_t pdate_size) + { + // Get the date as an integer + int rdigits; + double JD = (double)__gg__binary_value_from_qualified_field(&rdigits, + pdate, + pdate_offset, + pdate_size); + populate_ctm_from_JD(ctm, JD); + } + +static +void +populate_ctm_from_double_time(struct cobol_tm &ctm, double time) + { + // Get hours, minutes, and seconds + double intpart; + double fracpart = modf(time, &intpart); + + int hour = (int)intpart; + int second = hour % 60; + int minute = (hour / 60) % 60; + hour = hour / 3600; + ctm.ss = second; + ctm.mm = minute; + ctm.hh = hour; + ctm.nanoseconds = (int)(fracpart * 1000000000 + 0.5); + } + +static +void +populate_ctm_from_time( struct cobol_tm &ctm, + cblc_field_t *ptime, + size_t ptime_o, + size_t ptime_s, + cblc_field_t *poffset, + size_t poffset_o, + size_t poffset_s) + { + double time = get_value_as_double_from_qualified_field( ptime, + ptime_o, + ptime_s); + populate_ctm_from_double_time(ctm, time); + + if( poffset ) + { + int rdigits; + int value = (int)__gg__binary_value_from_qualified_field(&rdigits, + poffset, + poffset_o, + poffset_s); + if( rdigits ) + { + value /= __gg__power_of_ten(rdigits); + rdigits = 0; + } + ctm.tz_offset = value; + if( abs(value) >= 1440 ) + { + exception_raise(ec_argument_function_e); + } + } + else + { + ctm.tz_offset = 0; + } + } + +static void +convert_to_zulu(cobol_tm &ctm) + { + // Get the Julian Day + double JD = YMD_to_JD(ctm.YYYY, + ctm.MM, + ctm.DD); + // Get the time in seconds past midnight + double seconds_past_midnight = ctm.hh * 3600 + + ctm.mm * 60 + + ctm.ss; + // Subtract the UTC offset, which is given in minutes + seconds_past_midnight -= ctm.tz_offset * 60; + if( seconds_past_midnight < 0 ) + { + JD -= 1; + seconds_past_midnight += 86400; + } + else if( seconds_past_midnight >= 86400 ) + { + JD += 1; + seconds_past_midnight -= 86400; + } + JD -= JD_OF_1601_01_02; + populate_ctm_from_JD(ctm, JD); + populate_ctm_from_double_time(ctm, seconds_past_midnight); + if( ctm.YYYY < 1601 ) + { + ctm.YYYY = ctm.MM = ctm.DD = 0; + } + } + +static +void +ftime_replace(char *dest, char const * const dest_end, + char const *source, char const * const source_end, + char const * const ftime) + { + // This routine is highly dependent on the source format being correct. + int ncount; + const char *src; + bool saw_decimal_point = false; + bool saw_plus_sign = false; + char decimal_point = __gg__get_decimal_point(); + static const int OFFSET_TO_YYYY = 0; + static const int OFFSET_TO_MM = 4; + static const int OFFSET_TO_DD = 6; + static const int OFFSET_TO_HOUR = 9; + static const int OFFSET_TO_MINUTE = 11; + static const int OFFSET_TO_SECOND = 13; + static const int OFFSET_TO_FRACTION = 16; + static const int OFFSET_TO_OFFSET = 25; + static const int OFFSET_TO_OFFSET_HOUR = 26; + static const int OFFSET_TO_OFFSET_MINUTE = 28; + static const int OFFSET_TO_WEEK = 30; + static const int OFFSET_TO_DOW = 33; + static const int OFFSET_TO_DOY = 34; + static const int OFFSET_TO_ZZZZ = 37; + while( source < source_end && dest < dest_end ) + { + char fchar = *source; + if( fchar == internal_Y ) + { + // This can only be a YYYY + // But, we have a choice. If there is a 'W' in the format, then we + // need to use ZZZZ rather than YYYY: + src = ftime + OFFSET_TO_YYYY; + const char *p = source; + while(p < source_end) + { + if( *p++ == internal_W ) + { + src = ftime + OFFSET_TO_ZZZZ; + } + } + + ncount = 4; + } + else if( fchar == internal_M ) + { + // This can only be a MM + ncount = 2; + src = ftime + OFFSET_TO_MM; + } + else if( fchar == internal_D ) + { + // It can be a D, DD or DDD + if( source[2] == internal_D ) + { + ncount = 3; + src = ftime + OFFSET_TO_DOY; + } + else if( source[1] == internal_D ) + { + ncount = 2; + src = ftime + OFFSET_TO_DD; + } + else + { + ncount = 1; + src = ftime + OFFSET_TO_DOW; + } + } + else if( fchar == internal_plus ) + { + saw_plus_sign = true; + ncount = 1; + src = ftime + OFFSET_TO_OFFSET; + } + else if( fchar == internal_h ) + { + ncount = 2; + if(saw_plus_sign) + { + src = ftime + OFFSET_TO_OFFSET_HOUR; + } + else + { + src = ftime + OFFSET_TO_HOUR; + } + } + else if( fchar == internal_m ) + { + ncount = 2; + if(saw_plus_sign) + { + src = ftime + OFFSET_TO_OFFSET_MINUTE; + } + else + { + src = ftime + OFFSET_TO_MINUTE; + } + } + else if( fchar == decimal_point ) + { + saw_decimal_point = true; + ncount = 1; + src = source; + } + else if( fchar == internal_s ) + { + if(saw_decimal_point) + { + // There can be a variable number of fractional 's' + ncount = -1; + src = ftime + OFFSET_TO_FRACTION; + } + else + { + ncount = 2; + src = ftime + OFFSET_TO_SECOND; + } + } + else if( fchar == internal_W ) + { + ncount = 3; + src = ftime + OFFSET_TO_WEEK; + } + else + { + ncount = 1; + src = source; + } + + // Copy over the ncount characters to dest + if( ncount == -1 ) + { + // This indicates special processing for a variable number of 's' + // characters + while(*source == 's' && dest < dest_end) + { + source += 1; + *dest++ = *src++; + } + } + else + { + source += ncount; + while(ncount-- && dest < dest_end) + { + *dest++ = *src++; + } + } + } + } + +// +// +// Beyond this point, we are implementing phase 2 of intrinsics. These routines +// are intended to be "better" than the ones above. In an ideal world, +// eventually all of the above routines will migrate down here, and this comment +// will be removed. Bob Dubner, 2023-01-18 + +// Although not, of course, necessary, these routines are being placed in +// alphabetical order by the COBOL function name: + +extern "C" +void +__gg__abs(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION ABS + _Float128 value; + value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + if( value < 0 ) + { + value = -value; + } + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__acos( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION ACOS + _Float128 value; + value = __gg__float128_from_qualified_field(source, source_offset, source_size); + + if( value < -1.00Q || value > +1.00Q ) + { + exception_raise(ec_argument_function_e); + value = WEIRD_TRANSCENDENT_RETURN_VALUE; + } + else + { + value = acosf128(value); + } + + __gg__float128_to_field( dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__annuity(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_offset, + size_t arg1_size, + cblc_field_t *arg2, + size_t arg2_offset, + size_t arg2_size) + { + // FUNCTION ANNUITY + + _Float128 retval = 0; + + _Float128 val1 = fabsf128(__gg__float128_from_qualified_field(arg1, + arg1_offset, + arg1_size)); + _Float128 val2 = fabsf128(__gg__float128_from_qualified_field(arg2, + arg2_offset, + arg2_size)); + if( val2 > 0) + { + if( val1 < 0 ) + { + exception_raise(ec_argument_function_e); + } + else if( val1 == 0 ) + { + retval = 1/val2; + } + else + { + retval = val1 / (1- powf128( (1+val1), -val2 )); + } + } + else + { + exception_raise(ec_argument_function_e); + } + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + +extern "C" +void +__gg__asin( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION ASIN + + _Float128 value; + value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + + if( value < -1.0Q || value > +1.00Q ) + { + exception_raise(ec_argument_function_e); + value = WEIRD_TRANSCENDENT_RETURN_VALUE; + } + else + { + value = asinf128(value); + } + + __gg__float128_to_field( dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__atan( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION ATAN + + _Float128 value; + value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + + value = atanf128(value); + + __gg__float128_to_field( dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__byte_length(cblc_field_t *dest, + cblc_field_t */*source*/, + size_t /*source_offset*/, + size_t source_size) + { + // FUNCTION BYTE-LENGTH + __int128 value = source_size; + __gg__int128_to_field(dest, + value, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__char( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + int rdigits; + + // The CHAR function takes an integer, the ordinal position. It + // returns a single-character string, which is the character at that + // ordinal position. + + // 'A', with the ascii value of 65, is at the ordinal position 66. + + int ordinal = (int)(__gg__binary_value_from_qualified_field(&rdigits, + source, + source_offset, + source_size)); + ordinal /= __gg__power_of_ten(rdigits); + int ch = ordinal-1; + memset(dest->data, internal_space, dest->capacity); + dest->data[0] = ch; + } + +extern "C" +void +__gg__combined_datetime(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_offset, + size_t arg1_size, + cblc_field_t *arg2, + size_t arg2_offset, + size_t arg2_size) + { + int rdigits; + + __int128 val1 = (int)(__gg__binary_value_from_qualified_field(&rdigits, + arg1, + arg1_offset, + arg1_size)); + __int128 val2 = (int)(__gg__binary_value_from_qualified_field(&rdigits, + arg2, + arg2_offset, + arg2_size)); + __int128 value = val1 * 1000000 + val2; + __gg__int128_to_field(dest, + value, + 6, + truncation_e, + NULL); + } + +extern "C" +void +__gg__concat( cblc_field_t *dest, + size_t ncount) + { + size_t bytes = 0; + size_t offset = 0; + for(size_t i=0; idata + offset, + __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i], + __gg__treeplet_1s[i]); + offset += __gg__treeplet_1s[i]; + } + } + +extern "C" +void +__gg__cos(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION COS + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + value = cosf128(value); + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__current_date(cblc_field_t *dest) + { + // FUNCTION CURRENT-DATE + struct timespec tp = {}; + __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + + char retval[DATE_STRING_BUFFER_SIZE]; + timespec_to_string(retval, tp); + ascii_to_internal_str(retval, strlen(retval)); + string_to_dest(dest, retval); + } + +extern "C" +void +__gg__seconds_past_midnight(cblc_field_t *dest) + { + // SECONDS-PAST-MIDNIGHT + struct timespec tp = {}; + struct tm tm; + __int128 retval=0; + + __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + localtime_r(&tp.tv_sec, &tm); + + retval += tm.tm_hour; + retval *= 60; + retval += tm.tm_min; + retval *= 60; + retval += tm.tm_sec; + retval *= 1000000000; + retval += tp.tv_nsec; + __gg__int128_to_field(dest, + retval, + 9, + truncation_e, + NULL); + } + +extern "C" +void +__gg__date_of_integer(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION DATE-OF-INTEGER + int rdigits; + double JD = (double)__gg__binary_value_from_qualified_field(&rdigits, + source, + source_offset, + source_size); + JD += JD_OF_1601_01_02; + int Y; + int M; + int D; + JD_to_YMD(Y, M, D, JD); + int retval = Y*10000 + M*100 + D; + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__date_to_yyyymmdd( cblc_field_t *dest, + cblc_field_t *par1, + size_t par1_o, + size_t par1_s, + cblc_field_t *par2, + size_t par2_o, + size_t par2_s, + cblc_field_t *par3, + size_t par3_o, + size_t par3_s) + { + // FUNCTION DATE-TO-YYYYMMDD + // See the discussion in ISO/IEC 2014-1989 Section 15.20 + int rdigits; + int arg1 = (int)__gg__binary_value_from_qualified_field(&rdigits, par1, par1_o, par1_s); + int arg2 = (int)__gg__binary_value_from_qualified_field(&rdigits, par2, par2_o, par2_s ); + int arg3 = (int)__gg__binary_value_from_qualified_field(&rdigits, par3, par3_o, par3_s); + + int yy = arg1/10000; + int mmdd = arg1%10000; + + int retval = year_to_yyyy(yy, arg2, arg3) * 10000 + mmdd; + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__day_of_integer( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION DAY-OF_INTEGER + int rdigits; + double JD = (double)__gg__binary_value_from_qualified_field(&rdigits, + source, + source_offset, + source_size); + JD += JD_OF_1601_01_02; + int Y; + int M; + int D; + JD_to_YMD(Y, M, D, JD); + + double start_of_year = YMD_to_JD(Y, 1, 1); + + __int128 retval = Y * 1000 + int(JD - start_of_year) + 1; + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__day_to_yyyyddd( cblc_field_t *dest, + cblc_field_t *par1, + size_t par1_o, + size_t par1_s, + cblc_field_t *par2, + size_t par2_o, + size_t par2_s, + cblc_field_t *par3, + size_t par3_o, + size_t par3_s) + { + // FUNCTION DAY-TO-YYYYDDD + // See the discussion in ISO/IEC 2014-1989 Section 15.20 + int rdigits; + int arg1 = (int)__gg__binary_value_from_qualified_field(&rdigits, par1, par1_o, par1_s); + int arg2 = (int)__gg__binary_value_from_qualified_field(&rdigits, par2, par2_o, par2_s ); + int arg3 = (int)__gg__binary_value_from_qualified_field(&rdigits, par3, par3_o, par3_s); + + int yy = arg1/1000; + int ddd = arg1%1000; + + int retval = year_to_yyyy(yy, arg2, arg3) * 1000 + ddd; + + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__e(cblc_field_t *dest) + { + // FUNCTION E + static _Float128 e = 2.7182818284590452353602874713526624977572Q; + __gg__float128_to_field(dest, + e, + truncation_e, + NULL); + } + +extern "C" +void +__gg__exp(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION EXP + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + value = expf128(value); + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__exp10(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION EXP10 + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + value = powf128(10.0Q, value); + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__factorial(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION FACTORIAL + int rdigits; + int N = (int)__gg__binary_value_from_qualified_field( &rdigits, + source, + source_offset, + source_size); + while(rdigits--) + { + N /= 10; + } + + __int128 retval = 1; + + while( N > 1 ) + { + retval *= N--; + } + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__formatted_current_date( cblc_field_t *dest, // Destination string + cblc_field_t *input, // datetime format + size_t input_offset, + size_t input_size) + { + // FUNCTION CURRENT-DATE + + // Establish the destination, and set it to spaces + char *d = (char *)dest->data; + char *dend = d + dest->capacity; + memset(d, internal_space, dest->capacity); + + // Establish the formatting string: + char *format = (char *)(input->data+input_offset); + char *format_end = format + input_size; + + bool is_zulu = false; + + char *p = format; + while( p < format_end ) + { + int ch = *p++; + if( ch == internal_Z ) + { + is_zulu = true; + break; + } + } + + struct timespec ts = {}; + __gg__clock_gettime(CLOCK_REALTIME, &ts); + + struct tm tm = {}; + tm.tm_zone = "GMT"; + if( is_zulu ) + { + gmtime_r(&ts.tv_sec, &tm); + } + else + { + localtime_r(&ts.tv_sec, &tm); + } + + struct cobol_tm ctm = {}; + populate_ctm_from_tm(ctm, tm); + + ctm.nanoseconds = ts.tv_nsec; + + tzset(); + // Convert seconds west of UTC to minutes east of UTC + ctm.tz_offset = -timezone/60; + + char achftime[64]; + get_all_time(achftime, ctm); + ftime_replace(d, dend, format, format_end, achftime); + } + +extern "C" +void +__gg__formatted_date(cblc_field_t *dest, // Destination string + cblc_field_t *arg1, // datetime format + size_t arg1_offset, + size_t arg1_size, + cblc_field_t *arg2, // integer date + size_t arg2_offset, + size_t arg2_size) + { + // FUNCTION FORMATTED-DATE + + // Establish the destination, and set it to spaces + char *d = (char *)dest->data; + char *dend = d + dest->capacity; + memset(d, internal_space, dest->capacity); + + // Establish the formatting string: + char *format = (char *)(arg1->data+arg1_offset); + char *format_end = format + arg1_size; + + struct cobol_tm ctm = {}; + + populate_ctm_from_date(ctm, arg2, arg2_offset, arg2_size); + + char achftime[64]; + get_all_time(achftime, ctm); + if( __gg__exception_code ) + { + memset(d, internal_space, dend-d); + } + else + { + ftime_replace(d, dend, format, format_end, achftime); + __gg__adjust_dest_size(dest, format_end-format); + } + } + +extern "C" +void +__gg__formatted_datetime( cblc_field_t *dest, // Destination string + cblc_field_t *par1, // datetime format + size_t par1_o, + size_t par1_s, + cblc_field_t *par2, // integer date + size_t par2_o, + size_t par2_s, + cblc_field_t *par3, // numeric time + size_t par3_o, + size_t par3_s, + cblc_field_t *par4, // optional offset in seconds + size_t par4_o, + size_t par4_s + ) + { + // FUNCTION FORMATTED-DATETIME + + // Establish the destination, and set it to spaces + char *d = (char *)dest->data; + char *dend = d + dest->capacity; + memset(d, internal_space, dest->capacity); + + // Establish the formatting string: + char *format = (char *)(par1->data+par1_o); + char *format_end = format + par1_s; + trim_trailing_spaces(format, format_end); + bool is_zulu = is_zulu_format(format, format_end); + + struct cobol_tm ctm = {}; + + populate_ctm_from_date(ctm, par2, par2_o, par2_s); + populate_ctm_from_time( ctm, + par3, par3_o, par3_s, + par4, par4_o, par4_s); + + if( is_zulu ) + { + convert_to_zulu(ctm); + } + + char achftime[64]; + get_all_time(achftime, ctm); + if( __gg__exception_code ) + { + memset(d, internal_space, dend-d); + } + else + { + ftime_replace(d, dend, format, format_end, achftime); + __gg__adjust_dest_size(dest, format_end-format); + } + } + +extern "C" +void +__gg__formatted_time( cblc_field_t *dest,// Destination string + cblc_field_t *par1, // datetime format + size_t par1_o, + size_t par1_s, + cblc_field_t *par2,// numeric time + size_t par2_o, + size_t par2_s, + cblc_field_t *par4, // optional offset in seconds + size_t par4_o, + size_t par4_s) + + { + // FUNCTION FORMATTED-TIME + + // Establish the destination, and set it to spaces + char *d = (char *)dest->data; + char *dend = d + dest->capacity; + memset(d, internal_space, dest->capacity); + + // Establish the formatting string: + char *format = (char *)(par1->data+par1_o); + char *format_end = format + par1_s; + trim_trailing_spaces(format, format_end); + bool is_zulu = is_zulu_format(format, format_end); + + struct cobol_tm ctm = {}; + populate_ctm_from_time( ctm, + par2, + par2_o, + par2_s, + par4, + par4_o, + par4_s); + + if( is_zulu ) + { + convert_to_zulu(ctm); + } + + char achftime[64]; + get_all_time(achftime, ctm); + if( __gg__exception_code ) + { + memset(d, internal_space, dend-d); + } + else + { + ftime_replace(d, dend, format, format_end, achftime); + __gg__adjust_dest_size(dest, format_end-format); + } + } + +extern "C" +void +__gg__integer(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION INTEGER + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + value = floorf128(value); + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__integer_of_date(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION INTEGER-OF-DATE + int rdigits; + long argument_1 = (long)(__gg__binary_value_from_qualified_field(&rdigits, + source, + source_offset, + source_size)); + + int retval = 0; + static const int max_days[13] = {0, 31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31}; + + int year = (long)argument_1/10000; + int month = (long)argument_1/100 % 100; + int day = (long)argument_1 % 100; + + // We need to check for validity in the proleptic Gregorian calendar. + + int max_day = 0; + if( month >= 1 && month <= 12 ) + { + max_day = max_days[month]; + } + if( max_day == 28 && (((year%4) == 0 && ((year)%100) != 0) || ((year%400) == 0) )) + { + // Year is divisible by four, but is not divisible by 100, so this + // is a leap year. + max_day += 1; + } + if( day < 1 || day > max_day ) + { + max_day = 0; + } + if( max_day && year >= 1601 && year <= 9999 ) + { + // It's a valid Y/M/D: + double JD = YMD_to_JD(year, month, day); + + // Offset result so that 1601-01-01 comes back as the first day of + // the Gregorian Calendar + retval = (int)(JD - JD_OF_1601_01_02); + } + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__integer_of_day( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION INTEGER-OF-DAY + // Convert YYYYDDD to "integer date" + int rdigits; + int yyyyddd = (int)__gg__binary_value_from_qualified_field( &rdigits, + source, + source_offset, + source_size); + int yyyy = yyyyddd / 1000; + int ddd = yyyyddd % 1000; + + double JD = YMD_to_JD(yyyy, 1, 0) + ddd; + int retval = (int)(JD - JD_OF_1601_01_02); + + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__integer_part( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION INTEGER-PART + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + _Float128 retval = floorf128(fabsf128(value)); + + if( value < 0 ) + { + retval = -retval; + } + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + +extern "C" +void +__gg__fraction_part(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION INTEGER-PART + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + bool is_negative = false; + if( value < 0 ) + { + is_negative = true; + value = -value; + } + + _Float128 retval = value - floorf128(value); + + if( is_negative ) + { + retval = -retval; + } + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + +extern "C" +void +__gg__log( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION LOG + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + if( value <= 0.00 ) + { + exception_raise(ec_argument_function_e); + } + else + { + _Float128 retval = logf128(value); + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + } + +extern "C" +void +__gg__log10( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION LOG10 + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + if( value <= 0.00 ) + { + exception_raise(ec_argument_function_e); + } + else + { + _Float128 retval = log10f128(value); + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + } + +extern "C" +void +__gg__max(cblc_field_t *dest, + size_t ncount) + { + // FUNCTION MAX + + if( ( __gg__treeplet_1f[0]->type == FldAlphanumeric + || __gg__treeplet_1f[0]->type == FldLiteralA) ) + { + cblc_field_t *best_field ; + unsigned char *best_location ; + size_t best_length ; + int best_attr ; + bool best_move_all ; + bool best_address_of ; + + bool first_time = true; + assert(ncount); + for(size_t i=0; idata + __gg__treeplet_1o[i]; + best_length = __gg__treeplet_1s[i]; + best_attr = __gg__treeplet_1f[i]->attr; + best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + best_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + } + else + { + cblc_field_t *candidate_field = __gg__treeplet_1f[i]; + unsigned char *candidate_location = __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i]; + size_t candidate_length = __gg__treeplet_1s[i]; + int candidate_attr = __gg__treeplet_1f[i]->attr; + bool candidate_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + bool candidate_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + + int compare_result = __gg__compare_2( + candidate_field, + candidate_location, + candidate_length, + candidate_attr, + candidate_move_all, + candidate_address_of, + best_field, + best_location, + best_length, + best_attr, + best_move_all, + best_address_of, + 0); + if( compare_result >= 0 ) + { + best_field = candidate_field ; + best_location = candidate_location ; + best_length = candidate_length ; + best_attr = candidate_attr ; + best_move_all = candidate_move_all ; + best_address_of = candidate_address_of ; + } + } + if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) ) + { + // There is nothing left to do. + break; + } + } + } + + __gg__adjust_dest_size(dest, best_length); + dest->type = FldAlphanumeric; + memcpy(dest->data, best_location, best_length); + } + else + { + _Float128 retval; + bool first_time = true; + assert(ncount); + for(size_t i=0; i= retval ) + { + retval = candidate; + } + } + if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) ) + { + // There is nothing left to do for that input. + break; + } + } + } + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + } + +extern "C" +void +__gg__lower_case( cblc_field_t *dest, + cblc_field_t *input, + size_t input_offset, + size_t input_size) + { + size_t dest_length = dest->capacity; + size_t source_length = input_size; + memset(dest->data, internal_space, dest_length); + memcpy(dest->data, input->data+input_offset, std::min(dest_length, source_length)); + internal_to_ascii((char *)dest->data, dest_length); + std::transform(dest->data, dest->data + dest_length, dest->data, tolower); + ascii_to_internal_str((char *)dest->data, dest_length); + } + +extern "C" +void +__gg__mean( cblc_field_t *dest, + size_t ninputs) + { + // FUNCTION MEAN + size_t k_count; + _Float128 sum = kahan_summation(ninputs, + __gg__treeplet_1f, + __gg__treeplet_1o, + __gg__treeplet_1s, + __gg__fourplet_flags, + &k_count); + sum /= k_count; + __gg__float128_to_field(dest, + sum, + truncation_e, + NULL); + } + +extern "C" +void +__gg__median( cblc_field_t *dest, + size_t ncount) + { + // FUNCTION MEDIAN + + // This is wasteful, because it allocates N values in order to sort them. It + // is also an O(NlogN) solution, when there are O(N) solutions available. + + // It has the merit of being very simple. + + // The future beckons, but not today. + + size_t list_size = 1; + + _Float128 *the_list = (_Float128 *)malloc(list_size *sizeof(_Float128)); + size_t k_count = 0; + assert(ncount); + for(size_t i=0; i= list_size) + { + list_size *= 2; + the_list = (_Float128 *)realloc(the_list, list_size *sizeof(_Float128)); + } + + the_list[k_count] = __gg__float128_from_qualified_field(__gg__treeplet_1f[i], + __gg__treeplet_1o[i], + __gg__treeplet_1s[i]); + k_count += 1; + if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) ) + { + // There is nothing left to do. + break; + } + } + } + std::sort(the_list, the_list+k_count); + + _Float128 retval; + size_t i=k_count/2; + if( k_count & 1 ) + { + retval = the_list[i]; + } + else + { + retval = (the_list[i-1] + the_list[i])/2.0; + } + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + free(the_list); + } + +extern "C" +void +__gg__midrange( cblc_field_t *dest, + size_t ncount) + { + // FUNCTION MIDRANGE + _Float128 val; + _Float128 min=0; + _Float128 max=0; + bool first_time = true; + assert(ncount); + for(size_t i=0; itype == FldAlphanumeric + || __gg__treeplet_1f[0]->type == FldLiteralA) ) + { + cblc_field_t *best_field ; + unsigned char *best_location ; + size_t best_length ; + int best_attr ; + bool best_move_all ; + bool best_address_of ; + + bool first_time = true; + assert(ncount); + for(size_t i=0; idata + __gg__treeplet_1o[i]; + best_length = __gg__treeplet_1s[i]; + best_attr = __gg__treeplet_1f[i]->attr; + best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + best_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + } + else + { + cblc_field_t *candidate_field = __gg__treeplet_1f[i]; + unsigned char *candidate_location = __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i]; + size_t candidate_length = __gg__treeplet_1s[i]; + int candidate_attr = __gg__treeplet_1f[i]->attr; + bool candidate_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + bool candidate_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + + int compare_result = __gg__compare_2( + candidate_field, + candidate_location, + candidate_length, + candidate_attr, + candidate_move_all, + candidate_address_of, + best_field, + best_location, + best_length, + best_attr, + best_move_all, + best_address_of, + 0); + if( compare_result < 0 ) + { + best_field = candidate_field ; + best_location = candidate_location ; + best_length = candidate_length ; + best_attr = candidate_attr ; + best_move_all = candidate_move_all ; + best_address_of = candidate_address_of ; + } + } + if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) ) + { + // There is nothing left to do. + break; + } + } + } + + __gg__adjust_dest_size(dest, best_length); + dest->type = FldAlphanumeric; + memcpy(dest->data, best_location, best_length); + } + else + { + _Float128 retval; + bool first_time = true; + assert(ncount); + for(size_t i=0; i= 0 ? 1 : -1 ; + sign_of_div *= arg2 >= 0 ? 1 : -1 ; + + __int128 div = ( arg1 / arg2 ) ; + if( sign_of_div < 0 ) + { + div -= 1; + } + + retval = arg1 - arg2 * div ; + } + + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +static int +numval( cblc_field_t *dest, + cblc_field_t *input, + size_t input_offset, + size_t input_size) + { + // Returns the one-based character position of a bad character + // returns zero if it is okay + + char *p = (char *)(input->data + input_offset); + char *pend = p + input_size; + + int errpos = 0; + __int128 retval = 0; + int retval_rdigits = 0; + + bool saw_digit= false; + char decimal_point = ascii_to_internal(__gg__get_decimal_point()); + bool in_fraction = false; + bool leading_sign = false; + bool is_negative = false; + enum + { + SPACE1, + SPACE2, + DIGITS, + SPACE3, + SPACE4, + } state = SPACE1; + + if( input_size == 0 ) + { + errpos = 1; + goto done; + } + while( p < pend ) + { + unsigned char ch = *p++; + errpos += 1; + switch( state ) + { + case SPACE1: + // We tolerate spaces, and expect to end with a sign, digit, + // or decimal point: + if( ch == internal_space ) + { + continue; + } + if( ch == internal_plus ) + { + leading_sign = true; + state = SPACE2; + break; + } + if( ch == internal_minus ) + { + leading_sign = true; + is_negative = true; + state = SPACE2; + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + saw_digit = true; + retval = ch & 0xF; + state = DIGITS; + break; + } + if( ch == decimal_point ) + { + in_fraction = true; + state = DIGITS; + break; + } + // This is a bad character; errpos is correct + goto done; + break; + + case SPACE2: + // We tolerate spaces, and expect to end with a digit or decimal point: + if( ch == internal_space ) + { + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + saw_digit = true; + retval = ch & 0xF; + state = DIGITS; + break; + } + if( ch == decimal_point ) + { + in_fraction = true; + state = DIGITS; + break; + } + // This is a bad character; errpos is correct + goto done; + break; + + case DIGITS: + // We tolerate digits. We tolerate one decimal point. We expect to + // end with a space, a sign, "DB" or "CR", or the the end of the string + // It's a bit complicated + + if( ch >= internal_0 && ch <= internal_9 ) + { + saw_digit = true; + retval *= 10; + retval += ch & 0xF; + if( in_fraction ) + { + retval_rdigits += 1; + } + break; + } + if( ch == decimal_point && in_fraction ) + { + // Only one decimal is allowed + goto done; + } + if( ch == decimal_point ) + { + in_fraction = true; + break; + } + if( ch == internal_space ) + { + state = SPACE3; + break; + } + if( ch == internal_plus && leading_sign) + { + // We are allowed leading or trailing signs, but not both + goto done; + } + if( ch == internal_minus && leading_sign) + { + // We are allowed leading or trailing signs, but not both + goto done; + } + if( ch == internal_plus ) + { + state = SPACE4; + break; + } + if( ch == internal_minus ) + { + is_negative = true; + state = SPACE4; + break; + } + if( tolower(ch) == 'd' ) + { + if( leading_sign ) + { + goto done; + } + ch = *p++; + errpos += 1; + if( p > pend || tolower(ch) != 'b' ) + { + goto done; + } + is_negative = true; + state = SPACE4; + break; + } + if( tolower(ch) == 'c' ) + { + if( leading_sign ) + { + goto done; + } + ch = *p++; + errpos += 1; + if( p > pend || tolower(ch) != 'r' ) + { + goto done; + } + is_negative = true; + state = SPACE4; + break; + } + // This is a bad character; errpos is correct + goto done; + break; + + case SPACE3: + // We tolerate spaces, or we end with a sign: + if( ch == internal_space ) + { + break; + } + if( ch == internal_plus && leading_sign) + { + // We are allowed leading or trailing signs, but not both + goto done; + } + if( ch == internal_minus && leading_sign) + { + // We are allowed leading or trailing signs, but not both + goto done; + } + if( ch == internal_plus ) + { + state = SPACE4; + break; + } + if( ch == internal_minus ) + { + is_negative = true; + state = SPACE4; + break; + } + if( tolower(ch) == 'd' ) + { + if( leading_sign ) + { + goto done; + } + ch = *p++; + errpos += 1; + if( p > pend || tolower(ch) != 'b' ) + { + goto done; + } + is_negative = true; + state = SPACE4; + break; + } + if( tolower(ch) == 'c' ) + { + if( leading_sign ) + { + goto done; + } + ch = *p++; + errpos += 1; + if( p > pend || tolower(ch) != 'r' ) + { + goto done; + } + is_negative = true; + state = SPACE4; + break; + } + goto done; + break; + case SPACE4: + if( ch == internal_space ) + { + break; + } + goto done; + break; + } + } + if( saw_digit ) + { + errpos = 0; + } + else if( p == pend ) + { + // If we got to the end without seeing adigit, we need to bump the + // error pointer: + errpos += 1; + } + + done: + if(errpos) + { + retval = 0; + } + if( is_negative ) + { + retval = -retval; + } + if(dest) + { + __gg__int128_to_field(dest, + retval, + retval_rdigits, + truncation_e, + NULL); + } + return errpos; + } + +static +int +numval_c( cblc_field_t *dest, + cblc_field_t *src, + size_t src_offset, + size_t src_size, + cblc_field_t *crcy, + size_t crcy_offset, + size_t crcy_size + ) + { + size_t errcode = 0; + + char *pstart = (char *)(src->data+src_offset); + char *pend = pstart + src_size; + char *p = pstart; + + _Float128 retval = 0; + int sign = 0; + int rdigits = 0; + int rdigit_bump = 0; + unsigned char decimal_point = ascii_to_internal(__gg__get_decimal_point()); + unsigned char decimal_separator = ascii_to_internal(__gg__get_decimal_separator()); + + char *currency_start; + char *currency_end; + if( crcy ) + { + currency_start = (char *)(crcy->data+crcy_offset); + currency_end = currency_start + crcy_size; + } + else + { + currency_start = __gg__get_default_currency_string(); + currency_end = currency_start + strlen(currency_start); + } + char *pcurrency = currency_start; + // Trim off spaces from the currency: + while( *pcurrency == internal_space && pcurrency < currency_end ) + { + pcurrency += 1; + } + + while( *(currency_end-1) == internal_space && currency_end > currency_start ) + { + currency_end -= 1; + } + + // We will do this as a state machine: + + enum + { + first_space, + first_sign, + second_space, + currency, + before_digits, + digits, + after_digits, + second_sign, + final_space, + } state = first_space; + + while( p < pend ) + { + unsigned char ch = *p++; + switch( state ) + { + case first_space : + // Eat up spaces, if any, and then dispatch on the first non-space: + if( ch != internal_space ) + { + // ch can now be a plus, a minus, a digit, or the first character + // of the currency string + if( ch == internal_plus || ch == internal_minus ) + { + state = first_sign; + // Decrement to pointer in order to pick up the character again + p -= 1; + } + else if( ch == *pcurrency ) + { + state = currency; + p -= 1; + } + else if( (ch >= internal_0 && ch <= internal_9) + || ch == decimal_point ) + { + state = digits; + p -= 1; + } + else + { + // We have a bad character. Set the errcode to be the position of + // the bad character, and adjust p to break out of the loop. + // Set the state so that the default error processing is suppressed + state = final_space; + errcode = p - pstart; + p = pend; + } + } + break; + + case first_sign : + // We know the character is a plus or a minus: + if( ch == internal_plus ) + { + sign = 1; + state = second_space; + } + else + { + sign = -1; + state = second_space; + } + break; + + case second_space : + // Eat up spaces, if any. This segment has to end with a currency or + // a digit: + if( ch != internal_space ) + { + if( ch == *pcurrency ) + { + state = currency; + p -= 1; + } + else if( (ch >= internal_0 && ch <= internal_9) + || ch == decimal_point ) + { + state = digits; + p -= 1; + } + else + { + // We have a bad character. Set the errcode to be the position of + // the bad character, and adjust p to break out of the loop. + state = final_space; + errcode = p - pstart; + p = pend; + } + } + break; + + case currency : + // At this point, the only valid character is the next character + // in the currency string: + if( pcurrency >= currency_end ) + { + // Hey! Look at us! We got through the whole currency string. + state = before_digits; + p -= 1; + } + else if( ch == *pcurrency++) + { + // We are still marching through the currency + } + else + { + // We have a bad character: + errcode = p - pstart; + state = final_space; + p = pend; + } + break; + + case before_digits : + // Eat up spaces, if any. This segment has to end with a digit + if( ch != internal_space ) + { + if( (ch >= internal_0 && ch <= internal_9) + || ch == decimal_point ) + { + state = digits; + p -= 1; + } + else + { + // We have a bad character. Set the errcode to be the position of + // the bad character, and adjust p to break out of the loop. + state = final_space; + errcode = p - pstart; + p = pend; + } + } + break; + + case digits : + // The only thing allowed here are digits, decimal points, and + // decimal separators + if( ch >= internal_0 && ch <= internal_9 ) + { + // We have a digit. + rdigits += rdigit_bump; + retval *= 10; + retval += ch & 0x0F; + } + else if( ch == decimal_point && rdigit_bump) + { + // We have a second decimal_point, which is against the rules + errcode = p - pstart; + state = final_space; + p = pend; + } + else if( ch == decimal_separator ) + { + // Commas are ignored + } + else if( ch == decimal_point ) + { + rdigit_bump = 1; + } + else + { + // We have something that isn't a digit or decimal point or decimal + // separator: + state = after_digits; + p -= 1; + } + break; + + case after_digits : + // after digits, the only valid things are spaces, plus, minus, D, or C + if( ch != internal_space ) + { + if( ch == internal_plus + || ch == internal_minus + || ch == internal_D + || ch == internal_d + || ch == internal_C + || ch == internal_c ) + { + state = second_sign; + p -= 1; + } + } + break; + + case second_sign : + if( sign ) + { + // A second sign isn't allowed + state = final_space; + errcode = p - pstart; + p = pend; + } + if( ch == internal_plus ) + { + sign = 1; + } + else if( ch == internal_minus ) + { + sign = -1; + } + else if( (ch == internal_D || ch == internal_d) + && p < pend + && (*p == internal_B || *p == internal_b) ) + { + sign = -1; + p += 1; + } + else if( (ch == internal_C || ch == internal_c) + && p < pend + && (*p == internal_R || *p == internal_r) ) + { + sign = -1; + p += 1; + } + state = final_space; + break; + + case final_space : + // There should be only spaces until the end + if( ch == internal_space ) + { + continue; + } + // We have a non-space where there should be only space + state = final_space; + errcode = p - pstart; + p = pend; + break; + } + } + if( sign == 0 ) + { + sign = 1; + } + retval *= sign; + + if( state != after_digits && state != final_space && state != digits ) + { + // We broke out of the loop too soon: + errcode = pend - pstart + 1; + } + + if( dest ) + { + retval /= __gg__power_of_ten(rdigits); + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + return (int)errcode; + } + +extern "C" +void +__gg__numval( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + int errpos = numval(dest, source, source_offset, source_size); + if( errpos ) + { + exception_raise(ec_argument_function_e); + } + } + +extern "C" +void +__gg__test_numval(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + int retval = numval(NULL, source, source_offset, source_size); + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__numval_c( cblc_field_t *dest, + cblc_field_t *src, + size_t src_offset, + size_t src_size, + cblc_field_t *crcy, + size_t crcy_offset, + size_t crcy_size + ) + { + numval_c( dest, + src, + src_offset, + src_size, + crcy, + crcy_offset, + crcy_size); + } + +extern "C" +void +__gg__test_numval_c(cblc_field_t *dest, + cblc_field_t *src, + size_t src_offset, + size_t src_size, + cblc_field_t *crcy, + size_t crcy_offset, + size_t crcy_size + ) + { + int retval = numval_c(NULL, + src, + src_offset, + src_size, + crcy, + crcy_offset, + crcy_size); + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__ord(cblc_field_t *dest, + cblc_field_t *input, + size_t input_offset, + size_t /*input_size*/) + { + // We get our input in internal_character form. + char *arg = (char *)(input->data + input_offset); + + // The ORD function takes a single-character string and returns the + // ordinal position of that character. + + // In ASCII mode, an A is 0x41, so we return 0x42 + // In EBCDIC mode, an A is 0xC1, so we return 0xC2 + + size_t retval = (arg[0]&0xFF) + 1; + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__ord_min(cblc_field_t *dest, + size_t ninputs) + { + // Sets dest to the one-based ordinal position of the first occurrence + // of the biggest element in the list of refs[] + + int retval = -1; + int running_position = -1; + + cblc_field_t *best; + unsigned char *best_location; + size_t best_length; + int best_attr; + bool best_move_all; + bool best_address_of ; + + unsigned char *candidate_location; + size_t candidate_length; + int candidate_attr; + bool candidate_move_all; + bool candidate_address_of; + + for( size_t i=0; idata + __gg__treeplet_1o[i]; + best_length = __gg__treeplet_1s[i]; + best_attr = __gg__treeplet_1f[i]->attr; + best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + best_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + } + else + { + // We need to save the current adjustments, because __gg__compare + // is free to modify .location + candidate_location = __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i]; + candidate_length = __gg__treeplet_1s[i]; + candidate_attr = __gg__treeplet_1f[i]->attr; + candidate_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + candidate_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + + int compare_result = + __gg__compare_2( + __gg__treeplet_1f[i], + candidate_location, + candidate_length, + candidate_attr, + candidate_move_all, + candidate_address_of, + best, + best_location, + best_length, + best_attr, + best_move_all, + best_address_of, + 0); + if( compare_result < 0 ) + { + retval = running_position; + best = __gg__treeplet_1f[i]; + best_location = candidate_location; + best_length = candidate_length; + best_attr = candidate_attr; + best_move_all = candidate_move_all; + best_address_of = candidate_address_of; + } + } + if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) ) + { + // There is nothing left to do for that input. + break; + } + } + } + + retval += 1; + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__ord_max(cblc_field_t *dest, + size_t ninputs) + { + // Sets dest to the one-based ordinal position of the first occurrence + // of the biggest element in the list of refs[] + + int retval = -1; + int running_position = -1; + + cblc_field_t *best; + unsigned char *best_location; + size_t best_length; + int best_attr; + bool best_move_all; + bool best_address_of ; + + unsigned char *candidate_location; + size_t candidate_length; + int candidate_attr; + bool candidate_move_all; + bool candidate_address_of; + + for( size_t i=0; idata + __gg__treeplet_1o[i]; + best_length = __gg__treeplet_1s[i]; + best_attr = __gg__treeplet_1f[i]->attr; + best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + best_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + } + else + { + // We need to save the current adjustments, because __gg__compare + // is free to modify .location + candidate_location = __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i]; + candidate_length = __gg__treeplet_1s[i]; + candidate_attr = __gg__treeplet_1f[i]->attr; + candidate_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL); + candidate_address_of = !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF); + + int compare_result = + __gg__compare_2( + __gg__treeplet_1f[i], + candidate_location, + candidate_length, + candidate_attr, + candidate_move_all, + candidate_address_of, + best, + best_location, + best_length, + best_attr, + best_move_all, + best_address_of, + 0); + if( compare_result > 0 ) + { + retval = running_position; + best = __gg__treeplet_1f[i]; + best_location = candidate_location; + best_length = candidate_length; + best_attr = candidate_attr; + best_move_all = candidate_move_all; + best_address_of = candidate_address_of; + } + } + if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) ) + { + // There is nothing left to do for that input. + break; + } + } + } + + retval += 1; // Make the result one-based, as per COBOL specification + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__pi(cblc_field_t *dest) + { + // FUNCTION PI + + static _Float128 pi = 3.141592653589793238462643383279502884Q; + __gg__float128_to_field(dest, + pi, + truncation_e, + NULL); + } + +extern "C" +void +__gg__present_value(cblc_field_t *dest, + size_t ncount) + { + _Float128 discount = 0;; + _Float128 denom = 1; + + _Float128 retval = 0; + bool first_time = true; + for(size_t i=0; i 0); + for(size_t i=0; itype != FldAlphanumeric || + !(dest->attr & intermediate_e) ) + { + fprintf(stderr, + "We expect the target of a FUNCTION TIME to " + "be an intermediate alphanumeric\n"); + abort(); + } + dest->capacity = dest->offset; + + // No matter what, we want to find the leftmost non-space and the + // rightmost non-space: + + char *left = (char *)(arg1->data+arg1_offset); + char *right = left + arg1_size-1; + + // Find left and right: the first and last non-spaces + while( left <= right ) + { + if( *left != internal_space && *right != internal_space ) + { + break; + } + if( *left == internal_space ) + { + left += 1; + } + if( *right == internal_space ) + { + right -= 1; + } + } + if( type == LEADING ) + { + // We want to leave any trailing spaces, so we return 'right' to its + // original value: + right = (char *)(arg1->data+arg1_offset) + arg1_size-1; + } + else if( type == TRAILING ) + { + // We want to leave any leading spaces, so we return 'left' to its + // original value: + left = (char *)(arg1->data+arg1_offset); + } + + if( left > right ) + { + // When the arg1 input string was empty, we want left to be right+1. + // The left/right loop can sometimes end up with left equal to right+2. + // That needs to be fixed: + left = right+1; + } + + size_t ncount = right+1 - left; + __gg__adjust_dest_size(dest, ncount); + + // Because it's a temporary, we are weakly confident that we can change + // the capacity to match what we want. At this writing, we aren't 100% + // sure of the implications of the run-time capacity not matching what the + // compiler believes the capacity to be at compile-time. But we obviously + // think it'll be okay. + + char *dest_left = (char *)dest->data; + char *dest_right = dest_left + dest->capacity - 1; + char *dest_end = dest_left + dest->capacity; + + while( dest_left <= dest_right && left <= right ) + { + *dest_left++ = *left++; + } + while(dest_left < dest_end) + { + *dest_left++ = internal_space; + } + } + +static struct random_data *buf = NULL; +static char *state = NULL; +static const size_t state_len = 256; + +extern "C" +void +__gg__random( cblc_field_t *dest, + cblc_field_t *input, + size_t input_offset, + size_t input_size) + { + // This creates a thread-safe pseudo-random number generator + // using input as the seed + + // The return value is between zero and not quite one + + if( !buf ) + { + // This is the very first time through + buf = (random_data *)malloc(sizeof(struct random_data)); + buf->state = NULL; + state = (char *)malloc(state_len); + + struct timespec ts; + __gg__clock_gettime(CLOCK_REALTIME, &ts); + initstate_r( ts.tv_nsec, state, state_len, buf); + } + + int rdigits; + int seed = (int)__gg__binary_value_from_qualified_field(&rdigits, + input, + input_offset, + input_size); + srandom_r(seed, buf); + + int32_t retval_31; + random_r(buf, &retval_31); + // We are going to convert this to a value between zero and not quite one: + double retval = double(retval_31) / double(0x80000000UL); + __gg__double_to_target( dest, + retval, + truncation_e); + } + +extern "C" +void +__gg__random_next(cblc_field_t *dest) + { + // The return value is between zero and not quite one + + if( !buf ) + { + // This is the very first time through + buf = (random_data *)malloc(sizeof(struct random_data)); + buf->state = NULL; + state = (char *)malloc(state_len); + struct timespec ts; + __gg__clock_gettime(CLOCK_REALTIME, &ts); + initstate_r( ts.tv_nsec, state, state_len, buf); + } + int32_t retval_31; + random_r(buf, &retval_31); + + // We are going to convert this to a value between zero and not quite one: + double retval = double(retval_31) / double(0x80000000UL); + __gg__double_to_target( dest, + retval, + truncation_e); + } + +extern "C" +void +__gg__reverse(cblc_field_t *dest, + cblc_field_t *input, + size_t input_offset, + size_t input_size) + { + size_t dest_length = dest->capacity; + size_t source_length = input_size; + size_t length = std::min(dest_length, source_length); + memset(dest->data, internal_space, dest_length); + for(size_t i=0; idata[i] = (input->data+input_offset)[source_length-1-i]; + } + } + +extern "C" +void +__gg__sign( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION SIGN + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + + int retval; + if(value > 0) + { + retval = 1; + } + else if(value < 0) + { + retval = -1; + } + else + { + retval = 0; + } + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__sin(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION SIN + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + + value = sinf128(value); + + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__sqrt( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION SQRT + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + + if( value <= 0.0Q ) + { + exception_raise(ec_argument_function_e); + } + else + { + value = sqrtf128(value); + } + + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__standard_deviation( cblc_field_t *dest, + size_t ninputs) + { + // FUNCTION STANDARD-DEVIATION + _Float128 retval = variance(ninputs, + __gg__treeplet_1f, + __gg__treeplet_1o, + __gg__treeplet_1s, + __gg__fourplet_flags); + retval = sqrtf128(retval); + + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + +extern "C" +void +__gg__sum(cblc_field_t *dest, + size_t ninputs) + { + // FUNCTION SUM + size_t k_count; + _Float128 sum = kahan_summation(ninputs, + __gg__treeplet_1f, + __gg__treeplet_1o, + __gg__treeplet_1s, + __gg__fourplet_flags, + &k_count); + __gg__float128_to_field(dest, + sum, + truncation_e, + NULL); + } + +extern "C" +void +__gg__tan(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + // FUNCTION TAN + + _Float128 value = __gg__float128_from_qualified_field(source, + source_offset, + source_size); + value = tanf128(value); + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__test_date_yyyymmdd( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + int rdigits; + int yyyymmdd = (int)__gg__binary_value_from_qualified_field(&rdigits, + source, + source_offset, + source_size); + int retval; + int dd = yyyymmdd % 100; + int mmdd = yyyymmdd % 10000; + int mm = mmdd / 100; + int yyyy = yyyymmdd / 10000; + int jy; + int jm; + int jd; + double JD; + if( yyyymmdd < 16010000 || yyyymmdd > 99999999 ) + { + retval = 1; + } + else if( mm < 1 || mm > 12 ) + { + retval = 2; + } + else + { + // If there is something wrong with the number of days per month for a + // given year, the Julian Date conversion won't reverse properly. + // For example, January 32 will come back as February 1 + JD = YMD_to_JD(yyyy, mm, dd); + JD_to_YMD(jy, jm, jd, JD); + if( jd == dd && jm == mm && jy == yyyy ) + { + retval = 0; + } + else + { + retval = 3; + } + } + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__test_day_yyyyddd( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + int rdigits; + int yyyyddd = (int)__gg__binary_value_from_qualified_field(&rdigits, + source, + source_offset, + source_size); + int retval; + int ddd = yyyyddd % 1000; + int yyyy = yyyyddd / 1000; + int days_in_year; + + days_in_year = is_leap_year(yyyy); + + if( yyyyddd < 1601000 || yyyyddd > 9999999 ) + { + retval = 1; + } + else if( ddd < 1 || ddd > days_in_year) + { + retval = 2; + } + else + { + retval = 0; + } + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__upper_case( cblc_field_t *dest, + cblc_field_t *input, + size_t input_offset, + size_t input_size) + { + size_t dest_length = dest->capacity; + size_t source_length = input_size; + memset(dest->data, internal_space, dest_length); + memcpy(dest->data, input->data+input_offset, std::min(dest_length, source_length)); + internal_to_ascii((char *)dest->data, dest_length); + std::transform(dest->data, dest->data + dest_length, dest->data, toupper); + ascii_to_internal_str((char *)dest->data, dest_length); + } + +extern "C" +void +__gg__variance( cblc_field_t *dest, + size_t ncount) + { + // FUNCTION VARIANCE + _Float128 retval = variance(ncount, + __gg__treeplet_1f, + __gg__treeplet_1o, + __gg__treeplet_1s, + __gg__fourplet_flags); + __gg__float128_to_field(dest, + retval, + truncation_e, + NULL); + } + +extern "C" +void +__gg__when_compiled(cblc_field_t *dest, size_t tv_sec, long tv_nsec) + { + struct timespec tp = {}; + tp.tv_sec = tv_sec; + tp.tv_nsec = tv_nsec; + char retval[DATE_STRING_BUFFER_SIZE]; + timespec_to_string(retval, tp); + ascii_to_internal_str(retval, strlen(retval)); + string_to_dest(dest, retval); + } + +extern "C" +void +__gg__year_to_yyyy( cblc_field_t *dest, + cblc_field_t *par1, + size_t par1_o, + size_t par1_s, + cblc_field_t *par2, + size_t par2_o, + size_t par2_s, + cblc_field_t *par3, + size_t par3_o, + size_t par3_s) + { + // FUNCTION YEAR_TO_YYYY + int rdigits; + int yy = (int)__gg__binary_value_from_qualified_field(&rdigits, par1, par1_o, par1_s); + int arg2 = (int)__gg__binary_value_from_qualified_field(&rdigits, par2, par2_o, par2_s ); + int arg3 = (int)__gg__binary_value_from_qualified_field(&rdigits, par3, par3_o, par3_s); + + int retval = year_to_yyyy(yy, arg2, arg3); + + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +static +int +gets_int(int ndigits, char *p, char *pend, int *digits) + { + // This routine returns the value of the integer at p. If there is something + // wrong with the integer, it returns a negative number, the value being the + // position (starting at 1) where the problem is. + int retval = 0; + memset(digits, 0xFF, ndigits * sizeof(int)); + for(int i=1; i<=ndigits; i++) + { + if(p >= pend) + { + // We ran out of input too soon + retval = -i; + break; + } + int ch = *p++; + if( ch < internal_0 || ch > internal_9 ) + { + // This isn't a digit zero through nine + retval = -i; + break; + } + retval *= 10; + retval += ch & 0xF; + digits[i-1] = ch & 0xF; + } + return retval; + } + +static +int +gets_year(char *p, char *pend, struct cobol_tm &ctm) + { + // Populates ctm.YYYY, ctm.days_in_year, and ctm.weeks_in_year, which are + // all determined by the YYYY value. + + // Returns 0 if successful, and returns the ordinal position of the character + // where a four-character range with a year value of 1601 became impossible. + + int retval = 0; + int digits[4]; + int YYYY = gets_int(4, p, pend, digits); + + if( digits[0] == -1 || digits[0] == 0 ) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + if( digits[0] == 0 && digits[1] < 5) + { + return 2; + } + if( digits[2] == -1 ) + { + return 3; + } + if( digits[3] == -1 ) + { + return 4; + } + + if( YYYY >= 0 ) + { + // The year has to be > 1000 + if( YYYY < 1000 ) + { + // We fail on the initial zero + retval = 1; + } + else if( YYYY < 1600 ) + { + // We fail on the second digit + retval = 2; + } + else if( YYYY == 1600 ) + { + // We fail on the fourth digit + retval = 4; + } + else + { + // The year is a good value + ctm.YYYY = YYYY; + ctm.days_in_year = is_leap_year(YYYY); + ctm.weeks_in_year = weeks_in_year(YYYY); + } + } + else + { + retval = -YYYY; + } + return retval; + } + +static +int +gets_month(char *p, char *pend, struct cobol_tm &ctm) + { + // Populates ctm.MM + + // Returns either zero, or else the ordinal position of where the input + // processing failed. + + int digits[2]; + int retval = 0; + int MM = gets_int(2, p, pend, digits); + + if( digits[0] == -1 || digits[0] > 1) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + if( MM >= 0 ) + { + if( MM == 0 ) + { + // We know the month was wrong at the second zero + retval = 2; + } + if( MM >= 20 ) + { + // We know the month was wrong at the first digit + retval = 1; + } + else if( MM > 12 ) + { + // We are betweem 13 and 19, so it was the second digit + retval = 2; + } + ctm.MM = MM; + } + else + { + retval = -MM; + } + return retval; + } + +static +int +gets_day(char *p, char *pend, struct cobol_tm &ctm) + { + // Populates ctm.DD, ctm.day_of_week, ctm.week_of_year, ctm.day_of_week + + // The assumption is that YYYY and MM were populated before arriving here + + int digits[2]; + int retval = 0; + int DD = gets_int(2, p, pend, digits); + + if( digits[0] == -1 || digits[0] > 3) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + if(DD >= 0) + { + if( DD >= 0 ) + { + if( DD == 0) + { + // If zero, we know we failed at the second '0' in "00" + retval = 2; + } + else if( DD >= 40) + { + // 40 or more, then we knew there was trouble at the first digit + retval = 1; + } + else if(ctm.MM == 2 && DD >=30) + { + // It's February, so if we see 3x we know on the 3 that we are in + // error: + retval = 1; + } + else + { + static const int month_days[13] = {-1,31,28,31,30,31,30,31,31,30,31,30,31}; + int days_in_month = month_days[ctm.MM]; + if( ctm.MM == 2 && ctm.days_in_year == 366 ) + { + days_in_month = 29; + } + + if( DD > days_in_month ) + { + retval = 2; + } + else + { + // We have a good YYYY-MM-DD + ctm.DD = DD; + double JD = YMD_to_JD(ctm.YYYY, ctm.MM, DD); + double JD_Jan0 = YMD_to_JD(ctm.YYYY, 1, 0); + ctm.day_of_year = (int)(JD - JD_Jan0); + ctm.day_of_week = JD_to_DOW(JD); + } + } + } + } + else + { + retval = -DD; + } + return retval; + } + +static +int +gets_day_of_week(char *p, char *pend, struct cobol_tm &ctm) + { + // This is just a simple D, for day-of-week. The COBOL spec is that + // it be 1 to 7, 1 being Monday + int digits[1]; + int day_of_week = gets_int(1, p, pend, digits); + if( day_of_week<0 || day_of_week >7) + { + // The single character at source is no good: + return 1; + } + ctm.day_of_week = day_of_week; + + // It is a value 1 through 7. Convert it to 1 through 6: + day_of_week -= 1; + + // Find the day-of-year using COBOL week logic: + double JD_Jan4 = YMD_to_JD(ctm.YYYY, 1, 4); + double JD_Jan0 = JD_Jan4 - 4; + int dow_Jan4 = JD_to_DOW(JD_Jan4); + double week_zero = JD_Jan4 - dow_Jan4; + double JD = week_zero + (ctm.week_of_year-1)*7 + day_of_week; + + int day_of_year = (int)(JD - JD_Jan0); + + // It's possible for the year/week/day_of_week to be + // before Jan 1. This is the case for 1900-12-31, as one example; that + // date gets converted to 1901-W01-01 + if( day_of_year <= 0 ) + { + double JD_prior_year = YMD_to_JD(ctm.YYYY-1, 1, 0); + int day_of_prior_year = (int)(JD-JD_prior_year); + int days_in_prior_year = is_leap_year(ctm.YYYY-1); + if( day_of_prior_year > days_in_prior_year ) + { + return 1; + } + ctm.ZZZZ = ctm.YYYY + 1; + day_of_year = day_of_prior_year; + } + + // Arriving here means we have a good JD, which means we can decompose it + JD_to_YMD(ctm.YYYY, ctm.MM, ctm.DD, JD); + ctm.day_of_year = day_of_year; + return 0; + } + +static +int +gets_day_of_year(char *p, char *pend, struct cobol_tm &ctm) + { + // This is a three-digit day-of-year, 001 through 365,366 + int digits[3]; + int DDD = gets_int(3, p, pend, digits); + if( digits[0] == -1 || digits[0] > 3) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + if( digits[2] == -1 ) + { + return 3; + } + if( DDD < 0 ) + { + return -DDD; + } + + if( DDD == 0 ) + { + // We know we went wrong at the third '0' in "000" + return 3; + } + if( DDD >= 400 ) + { + // We know we went wrong at the first digit + return 1; + } + if( DDD >= 370 ) + { + // We know we went wrong at the second digit + return 2; + } + if( DDD > ctm.days_in_year ) + { + // We know we went wrong at the third digit + return 3; + } + // We know that DDD is a good value between 1 and ctm.days_in_year + ctm.day_of_year = DDD; + + double JD_Jan0 = YMD_to_JD(ctm.YYYY, 1, 0); + double JD = JD_Jan0 + DDD; + JD_to_YMD(ctm.YYYY, + ctm.MM, + ctm.DD, + JD); + ctm.day_of_week = JD_to_DOW(JD); + return 0; + } + +static +int +gets_week(char *p, char *pend, struct cobol_tm &ctm) + { + // This is a two-digit value, 01 through 52,53 + int digits[2]; + int ww = gets_int(2, p, pend, digits); + if( digits[0] == -1 || digits[0] > 5 ) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + if( ww < 0 ) + { + return -ww; + } + + if( ww == 0 ) + { + // We know we went wrong at the second '0' in "00" + return 2; + } + if( ww >= 60 ) + { + // We know we went wrong at the first digit + return 1; + } + if( ww > ctm.weeks_in_year ) + { + // We know we went wrong at the second digit + return 2; + } + // We know that ww is a good value for this year. + ctm.week_of_year = ww; + return 0; + } + +static +int +gets_hours(char *p, char *pend, struct cobol_tm &ctm, bool in_offset) + { + // This is a two-digit value, 01 through 23 + int digits[2]; + int hh = gets_int(2, p, pend, digits); + + if( digits[0] == -1 || digits[0] > 2 ) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + + if( hh < 0 ) + { + return -hh; + } + + if( hh >= 30 ) + { + // We know we went wrong at the first digit + return 1; + } + + if( hh >= 24 ) + { + // We know we went wrong at the first digit + return 2; + } + + if( in_offset ) + { + ctm.tz_offset = 60*hh; + } + else + { + ctm.hh = hh; + } + return 0; + } + +static +int +gets_minutes(char *p, char *pend, struct cobol_tm &ctm, bool in_offset) + { + // This is a two-digit value, 01 through 59 + int digits[2]; + int mm = gets_int(2, p, pend, digits); + if( digits[0] == -1 || digits[0] > 5 ) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + + if( mm < 0 ) + { + return -mm; + } + + if( mm >= 60 ) + { + // We know we went wrong at the first digit + return 1; + } + + if( in_offset ) + { + ctm.tz_offset += mm; + } + else + { + ctm.mm = mm; + } + return 0; + } + +static +int +gets_seconds(char *p, char *pend, struct cobol_tm &ctm) + { + // This is a two-digit value, 01 through 59 + int digits[2]; + int ss = gets_int(2, p, pend, digits); + if( digits[0] == -1 || digits[0] > 5 ) + { + return 1; + } + if( digits[1] == -1 ) + { + return 2; + } + if( ss < 0 ) + { + return -ss; + } + + if( ss >= 60 ) + { + // We know we went wrong at the first digit + return 1; + } + + ctm.ss = ss; + return 0; + } + +static +int +gets_nanoseconds(char *f, char *f_end, char *p, char *pend, struct cobol_tm &ctm) + { + // Because nanoseconds digits to the right of the decimal point can vary from + // one digit to our implementation-specific limit of nine characters, this + // routine is slightly different. If there is an error, that causes a + // positive return value. A negative return value contains the number of + // digits we processed + + int errpos = 0; + int ncount = 0; + int nanoseconds = 0; + + char *pinit = p; + while( f < f_end && *f == internal_s && p < pend ) + { + f += 1; + int ch = *p++; + errpos += 1; + + if( ch < internal_0 || ch > internal_9 ) + { + // Let our caller know we see a bad character + return errpos; + } + + if(ncount < 9) + { + nanoseconds *= 10; + nanoseconds += ch & 0x0F; + } + ncount += 1; + } + while(ncount++ < 9) + { + nanoseconds *= 10; + } + ctm.nanoseconds = nanoseconds; + + return -((int)(p - pinit)); + } + +static +int +fill_cobol_tm(cobol_tm &ctm, + cblc_field_t *par1, + size_t par1_offset, + size_t par1_size, + cblc_field_t *par2, + size_t par2_offset, + size_t par2_size) + { + // Establish the formatting string: + char *format = (char *)(par1->data+par1_offset); + char *format_end = format + par1_size; + + // Establish the string to be checked: + char *source = (char *)(par2->data+par2_offset); + char *source_end = source + par2_size; + + // Let's eliminate trailing spaces... + trim_trailing_spaces(format, format_end); + trim_trailing_spaces(source, source_end); + + bool in_offset = false; + bool in_nanoseconds = false; + + char decimal_point = __gg__get_decimal_point(); + + // We keep constant track of the current error location. + int retval = 1; + int errpos; + + // At this juncture, we expect both the format and the source to have valid + // data. If they don't, it's because the source is too short, and thus + // retval is the failure point. + int bump; + while( format < format_end && source < source_end ) + { + char ch = *format; + + if( ch == internal_T + || ch == internal_colon + || ch == internal_minus + || ch == internal_W) + { + // These are just formatting characters. They need to be duplicated, + // but are otherwise ignored. + if( *source != ch ) + { + break; + } + bump = 1; + goto proceed; + } + + if( ch == internal_plus ) + { + // This flags a following hhmm offset. It needs to match a '+' or '-' + if( *source != internal_plus + && *source != internal_minus + && *source != internal_zero) + { + break; + } + if( *source == internal_zero ) + { + // The next four characters have to be zeroes + if( source[1] != internal_zero ) + { + retval += 1; + break; + } + if( source[2] != internal_zero ) + { + retval += 2; + break; + } + if( source[3] != internal_zero ) + { + retval += 3; + break; + } + if( source[4] != internal_zero ) + { + retval += 4; + break; + } + } + + in_offset = true; + bump = 1; + goto proceed; + } + + if( ch == decimal_point ) + { + // This indicates we are starting to process fractional seconds + if( *source != decimal_point ) + { + break; + } + in_nanoseconds = true; + bump = 1; + goto proceed; + } + + if( ch == internal_Y ) + { + errpos = gets_year(source, source_end, ctm); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = 4; + goto proceed; + } + + if( ch == internal_M ) + { + errpos = gets_month(source, source_end, ctm); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = 2; + goto proceed; + } + + if( ch == internal_D ) + { + // We have three possibilities: DDD, DD, and D + if( format[1] != internal_D ) + { + // A singleton 'D' is a day-of-week + errpos = gets_day_of_week(source, source_end, ctm); + if( errpos > 0) + { + retval += errpos - 1; + break; + } + bump = 1; + } + else if( format[2] != internal_D ) + { + // This is DD, for day-of-month + errpos = gets_day(source, source_end, ctm); + if( errpos > 0) + { + retval += errpos - 1; + break; + } + bump = 2; + } + else + { + // Arriving here means that it is DDD, for day-of-year + // This is DD, for day-of-month + errpos = gets_day_of_year(source, source_end, ctm); + if( errpos > 0) + { + retval += errpos - 1; + break; + } + bump = 3; + } + goto proceed; + } + + if( ch == internal_w ) + { + errpos = gets_week(source, source_end, ctm); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = 2; + goto proceed; + } + + if( ch == internal_h ) + { + errpos = gets_hours(source, source_end, ctm, in_offset); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = 2; + goto proceed; + } + + if( ch == internal_m ) + { + errpos = gets_minutes(source, source_end, ctm, in_offset); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = 2; + goto proceed; + } + + if( ch == internal_s && !in_nanoseconds ) + { + errpos = gets_seconds(source, source_end, ctm); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = 2; + goto proceed; + } + + if( ch == internal_s && in_nanoseconds ) + { + // Peel off digits to the right of the decimal point one at a time + errpos = gets_nanoseconds(format, format_end, source, source_end, ctm); + if( errpos > 0 ) + { + retval += errpos - 1; + break; + } + bump = -errpos; + goto proceed; + } + + if( ch == internal_Z || ch == internal_z ) + { + // This has to be the end of the road + if( toupper(source[0]) != 'Z' ) + { + retval += 0; + break; + } + + convert_to_zulu(ctm); + bump = 1; + goto proceed; + } + + assert(false); + +proceed: + retval += bump; + format += bump; + source += bump; + } + + if( format >= format_end && source >= source_end) + { + // This means we processed the entire format string without seeing an error + retval = 0; + + // Otherwise, either the format or source was too short + } + return retval; + } + +extern "C" +void +__gg__test_formatted_datetime(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_offset, + size_t arg1_size, + cblc_field_t *arg2, + size_t arg2_offset, + size_t arg2_size) + + { + struct cobol_tm ctm = {}; + + int retval = fill_cobol_tm( ctm, + arg1, arg1_offset, arg1_size, + arg2, arg2_offset, arg2_size); + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__integer_of_formatted_date(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_offset, + size_t arg1_size, + cblc_field_t *arg2, + size_t arg2_offset, + size_t arg2_size) + { + struct cobol_tm ctm = {}; + + int retval = fill_cobol_tm( ctm, + arg1, arg1_offset, arg1_size, + arg2, arg2_offset, arg2_size); + if(retval) + { + retval = 0; // Indicates there was a problem with the input data + } + else + { + double JD = YMD_to_JD(ctm.YYYY, ctm.MM, ctm.DD); + + // Offset result so that 1601-01-01 comes back as the first day of + // the Gregorian Calendar + retval = (int)(JD - JD_OF_1601_01_02); + } + + __gg__int128_to_field(dest, + retval, + NO_RDIGITS, + truncation_e, + NULL); + } + +extern "C" +void +__gg__seconds_from_formatted_time(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_offset, + size_t arg1_size, + cblc_field_t *arg2, + size_t arg2_offset, + size_t arg2_size) + { + struct cobol_tm ctm = {}; + + double retval = fill_cobol_tm( ctm, + arg1, arg1_offset, arg1_size, + arg2, arg2_offset, arg2_size); + if(retval > 0) + { + retval = 0; // Indicates there was a problem with the input data + } + else + { + retval = (double)(ctm.hh * 3600 + ctm.mm * 60 + ctm.ss) + ctm.nanoseconds/1000000000.; + } + __gg__double_to_target( dest, + retval, + truncation_e); + } + +extern "C" +void +__gg__hex_of(cblc_field_t *dest, + cblc_field_t *field, + size_t field_offset, + size_t field_size) + { + static const char hex[17] = "0123456789ABCDEF"; + size_t bytes = field_size; + __gg__adjust_dest_size(dest, 2*bytes); + for(size_t i=0; idata+field_offset)[i]; + dest->data[2*i] = ascii_to_internal(hex[byte>>4]); + dest->data[2*i+1] = ascii_to_internal(hex[byte&0xF]); + } + } + +extern "C" +void +__gg__highest_algebraic(cblc_field_t *dest, + cblc_field_t *var, + size_t, + size_t) + { + __int128 result = 0; + __int128 result_rdigits = 0; + + if( var->attr & scaled_e ) + { + result = __gg__power_of_ten(var->digits) - 1; + if( var->rdigits<0 ) + { + result *= __gg__power_of_ten(-var->rdigits); + } + else + { + result_rdigits = var->digits + var->rdigits; + } + } + else if( var->digits == 0 ) + { + result = (1<<(var->capacity*8)) -1 ; + if( var->attr & signable_e ) + { + result >>=1 ; + } + } + else + { + result_rdigits = var->rdigits; + result = __gg__power_of_ten(var->digits) - 1; + } + __gg__int128_to_field(dest, + result, + result_rdigits, + truncation_e, + NULL); + } + +extern "C" +void +__gg__lowest_algebraic( cblc_field_t *dest, + cblc_field_t *var, + size_t, + size_t) + { + __int128 result = 0; + __int128 result_rdigits = 0; + + if( var->attr & scaled_e ) + { + result = __gg__power_of_ten(var->digits) - 1; + if( var->rdigits<0 ) + { + result *= __gg__power_of_ten(-var->rdigits); + } + else + { + result_rdigits = var->digits + var->rdigits; + } + if( var->attr & signable_e ) + { + result = -result; + } + else + { + result = 0; + } + } + else if( var->digits == 0 ) + { + result = (1<<(var->capacity*8)) -1 ; + if( var->attr & signable_e ) + { + result >>=1 ; + result += 1; + result = -result; + } + else + { + result = 0; + } + } + else + { + result_rdigits = var->rdigits; + result = __gg__power_of_ten(var->digits) - 1; + if( var->attr & signable_e ) + { + result = -result; + } + else + { + result = 0; + } + } + __gg__int128_to_field(dest, + result, + result_rdigits, + truncation_e, + NULL); + } + +static int +floating_format_tester(char const * const f, char * const f_end) + { + int retval = -1; + char decimal_point = __gg__get_decimal_point(); + + enum + { + SPACE1, + SPACE2, + DIGITS1, + DIGITS2, + SPACE3, + SPACE4, + SPACE5, + DIGITS3, + SPACE6, + } state = SPACE1; + ssize_t index = 0; + while(index < f_end - f) + { + char ch = f[index]; + switch(state) + { + case SPACE1: + if( ch == internal_space ) + { + // Just keep looking + break; + } + if( ch == internal_minus + || ch == internal_plus) + { + state = SPACE2; + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + state = DIGITS1; + break; + } + if( decimal_point ) + { + state = DIGITS2; + break; + } + // Disallowed character + retval = index; + break; + + case SPACE2: + if( ch == internal_space ) + { + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + state = DIGITS1; + break; + } + if( ch == decimal_point ) + { + state = DIGITS2; + break; + } + retval = index; + break; + + case DIGITS1: + if( ch >= internal_0 && ch <= internal_9 ) + { + break; + } + if( ch == decimal_point ) + { + state = DIGITS2; + break; + } + if( ch == internal_space ) + { + state = SPACE3; + break; + } + retval = index; + break; + + case DIGITS2: + if( ch >= internal_0 && ch <= internal_9 ) + { + break; + } + if( ch == internal_space ) + { + state = SPACE3; + break; + } + if( ch == internal_E || ch == internal_e ) + { + state = SPACE4; + break; + } + retval = index; + break; + + case SPACE3: + if( ch == internal_space ) + { + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + retval = index; + break; + } + if( ch == internal_E || ch == internal_e ) + { + state = SPACE4; + break; + } + retval = index; + break; + + case SPACE4: + if( ch == internal_space ) + { + break; + } + if( ch == internal_minus || ch == internal_plus ) + { + state = SPACE5; + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + state = DIGITS3; + break; + } + retval = index; + break; + + case SPACE5: + if( ch == internal_space ) + { + break; + } + if( ch >= internal_0 && ch <= internal_9 ) + { + state = DIGITS3; + break; + } + retval = index; + break; + + case DIGITS3: + if( ch >= internal_0 && ch <= internal_9 ) + { + break; + } + if( ch == internal_space ) + { + state = SPACE6; + break; + } + retval = index; + break; + + case SPACE6: + if( ch == internal_space ) + { + break; + } + retval = index; + break; + } + + if( retval > -1 ) + { + break; + } + index += 1; + } + + retval += 1; + return retval; + } + +extern "C" +void +__gg__numval_f( cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + _Float128 value = 0; + char *data = (char * )(source->data + source_offset); + char *data_end = data + source_size; + + int error = floating_format_tester(data, data_end); + + if( error || source_size >= 256 ) + { + exception_raise(ec_argument_function_e); + } + else + { + // Get rid of any spaces in the string + char ach[256]; + char *p = ach; + while( data < data_end ) + { + char ch = *data++; + if( ch != internal_space ) + { + *p++ = ch; + } + } + *p++ = '\0'; + value = strtof128(ach, NULL); + } + __gg__float128_to_field(dest, + value, + truncation_e, + NULL); + } + +extern "C" +void +__gg__test_numval_f(cblc_field_t *dest, + cblc_field_t *source, + size_t source_offset, + size_t source_size) + { + char *data = (char * )(source->data + source_offset); + char *data_end = data + source_size; + + int error = floating_format_tester(data, data_end); + + __gg__int128_to_field(dest, + error, + NO_RDIGITS, + truncation_e, + NULL); + } + +static bool +ismatch(char *a1, char *a2, char *b1, char *b2) + { + bool retval = true; + while( a1 < a2 && b1 < b2 ) + { + if( *a1++ != *b1++ ) + { + retval = false; + } + } + return retval; + } + +static bool +iscasematch(char *a1, char *a2, char *b1, char *b2) + { + bool retval = true; + while( a1 < a2 && b1 < b2 ) + { + if( tolower(*a1++) != tolower(*b1++) ) + { + retval = false; + } + } + return retval; + } + +static char * +strstr(char *haystack, char *haystack_e, char *needle, char *needle_e) + { + char *retval = NULL; + char *pend = haystack_e - (needle_e - needle); + while( haystack <= pend ) + { + if(ismatch(haystack, haystack_e, needle, needle_e)) + { + retval = haystack; + break; + } + haystack += 1; + } + return retval; + } + +static char * +strcasestr(char *haystack, char *haystack_e, char *needle, char *needle_e) + { + char *retval = NULL; + char *pend = haystack_e - (needle_e - needle); + while( haystack <= pend ) + { + if(iscasematch(haystack, haystack_e, needle, needle_e)) + { + retval = haystack; + break; + } + haystack += 1; + } + return retval; + } + +static char * +strlaststr(char *haystack, char *haystack_e, char *needle, char *needle_e) + { + char *retval = NULL; + char *pend = haystack_e - (needle_e - needle); + while( haystack <= pend ) + { + if(ismatch(haystack, haystack_e, needle, needle_e)) + { + retval = haystack; + } + haystack += 1; + } + return retval; + } + +static char * +strcaselaststr(char *haystack, char *haystack_e, char *needle, char *needle_e) + { + char *retval = NULL; + char *pend = haystack_e - (needle_e - needle); + while( haystack <= pend ) + { + if(iscasematch(haystack, haystack_e, needle, needle_e)) + { + retval = haystack; + } + haystack += 1; + } + return retval; + } + + +extern "C" +void __gg__substitute(cblc_field_t *dest, + cblc_field_t *arg1_f, + size_t arg1_o, + size_t arg1_s, + size_t N, + uint8_t *control + ) + { + // arg2 is the Group 1 triplet. + // arg3 is the Group 2 triplet + cblc_field_t **arg2_f = __gg__treeplet_1f; + size_t *arg2_o = __gg__treeplet_1o; + size_t *arg2_s = __gg__treeplet_1s; + cblc_field_t **arg3_f = __gg__treeplet_2f; + size_t *arg3_o = __gg__treeplet_2o; + size_t *arg3_s = __gg__treeplet_2s; + + ssize_t retval_size = 256; + char *retval = (char *)malloc(retval_size); + *retval = '\0'; + + char *haystack = (char *)(arg1_f->data + arg1_o); + char *haystack_e = haystack + arg1_s; + + ssize_t outdex = 0; + + char **pflasts = (char **)malloc(N * sizeof(char *)); + + if( arg1_s == 0 ) + { + exception_raise(ec_argument_function_e); + goto bugout; + } + + for( size_t i=0; idata+arg2_o[i]), + (char *)(arg2_f[i]->data+arg2_o[i]) + arg2_s[i]); + } + else if( control[i] & substitute_last_e) + { + pflasts[i] = strcaselaststr(haystack, + haystack_e, + (char *)(arg2_f[i]->data+arg2_o[i]), + (char *)(arg2_f[i]->data+arg2_o[i]) + arg2_s[i]); + } + else + { + pflasts[i] = NULL; + } + } + else + { + if( control[i] & substitute_first_e ) + { + pflasts[i] = strstr(haystack, + haystack_e, + (char *)(arg2_f[i]->data+arg2_o[i]), + (char *)(arg2_f[i]->data+arg2_o[i]) + arg2_s[i]); + } + else if( control[i] & substitute_last_e) + { + pflasts[i] = strlaststr(haystack, + haystack_e, + (char *)(arg2_f[i]->data+arg2_o[i]), + (char *)(arg2_f[i]->data+arg2_o[i]) + arg2_s[i]); + } + else + { + pflasts[i] = NULL; + } + } + } + + while( haystack < haystack_e ) + { + bool did_something = false; + for( size_t i=0; i retval_size ) + { + retval_size *= 2; + retval = (char *)realloc(retval, retval_size); + } + + // We checked earlier for FIRST/LAST matches + bool matched = pflasts[i] == haystack; + if( !matched ) + { + // It didn't match. But if it was flagged as FIRST or LAST, we need + // to skip it + + if( control[i] & (substitute_first_e|substitute_last_e) ) + { + continue; + } + + char *needle = (char *)(arg2_f[i]->data+arg2_o[i]); + char *needle_e = (char *)(arg2_f[i]->data+arg2_o[i]) + arg2_s[i]; + matched = (control[i] & substitute_anycase_e) && iscasematch( + haystack, + haystack_e, + needle, + needle_e); + if( !matched ) + { + matched = !(control[i] & substitute_anycase_e) && ismatch(haystack, + haystack_e, + needle, + needle_e) ; + } + } + if( matched ) + { + haystack += arg2_s[i]; + memcpy(retval + outdex, arg3_f[i]->data + arg3_o[i], arg3_s[i]); + outdex += arg3_s[i]; + did_something = true; + break; + } + } + if( !did_something ) + { + while( outdex + 1 > retval_size ) + { + retval_size *= 2; + retval = (char *)realloc(retval, retval_size); + } + retval[outdex++] = *haystack++; + } + } + + bugout: + __gg__adjust_dest_size(dest, outdex); + memcpy(dest->data, retval, outdex); + + free(pflasts); + free(retval); + } + +extern "C" +void +__gg__locale_compare( cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_o, + size_t arg1_s, + cblc_field_t *arg2, + size_t arg2_o, + size_t arg2_s, + cblc_field_t *arg_locale, + size_t /*arg_locale_o*/, + size_t /*arg_locale_s*/ + ) + { + char achretval[2] = "?"; + + if( arg_locale ) + { + // We don't yet know what to do with a locale + exception_raise(ec_locale_missing_e); + } + else + { + // Default locale + achretval[0] = '='; + size_t length = std::min(arg1_s, arg2_s); + for(size_t i=0; idata+arg1_o)[i] < (arg2->data+arg2_o)[i] ) + { + achretval[0] = '<'; + break; + } + if( (arg1->data+arg1_o)[i] > (arg2->data+arg2_o)[i] ) + { + achretval[0] = '>'; + break; + } + } + if( achretval[0] == '=' ) + { + if( arg1_s < arg2_s ) + { + achretval[0] = '<'; + } + else if( arg1_s > arg2_s ) + { + achretval[0] = '>'; + } + } + } + + __gg__adjust_dest_size(dest, 1); + ascii_to_internal_str(achretval, 1); + dest->data[0] = *achretval; + } + +extern "C" +void +__gg__locale_date(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_o, + size_t /*arg1_s*/, + cblc_field_t *arg_locale, + size_t /*arg_locale_o*/, + size_t /*arg_locale_s*/) + { + char ach[256] = " "; + + if( arg_locale ) + { + // We don't yet know what to do with a locale + exception_raise(ec_locale_missing_e); + } + else + { + // Default locale + tm tm; + memcpy(ach, arg1->data+arg1_o, 8); + ach[8] = '\0'; + long ymd = atoi(ach); + tm.tm_year = ymd/10000 - 1900; + tm.tm_mon = ymd/100 % 100; + tm.tm_mday = ymd % 100; + strcpy(ach, nl_langinfo(D_FMT)); + strftime(ach, sizeof(ach), nl_langinfo(D_FMT), &tm); + } + + __gg__adjust_dest_size(dest, strlen(ach)); + ascii_to_internal_str(ach, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } + +extern "C" +void +__gg__locale_time(cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_o, + size_t /*arg1_s*/, + cblc_field_t *arg_locale, + size_t /*arg_locale_o*/, + size_t /*arg_locale_s*/) + + { + char ach[256] = " "; + + if( arg_locale) + { + // We don't yet know what to do with a locale + exception_raise(ec_locale_missing_e); + } + else + { + // Default locale + tm tm = {}; + memcpy(ach, arg1->data+arg1_o, 8); + ach[8] = '\0'; + long hms = atoi(ach); + tm.tm_hour = hms/10000; + tm.tm_min = hms/100 % 100; + tm.tm_sec = hms % 100; + strftime(ach, sizeof(ach), nl_langinfo(T_FMT), &tm); + } + + __gg__adjust_dest_size(dest, strlen(ach)); + ascii_to_internal_str(ach, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } + +extern "C" +void +__gg__locale_time_from_seconds( cblc_field_t *dest, + cblc_field_t *arg1, + size_t arg1_o, + size_t arg1_s, + cblc_field_t *arg_locale, + size_t /*arg_locale_o*/, + size_t /*arg_locale_s*/) + { + char ach[256] = " "; + + if( arg_locale ) + { + // We don't yet know what to do with a locale + exception_raise(ec_locale_missing_e); + } + else + { + // Default locale + tm tm = {}; + + int rdigits; + long seconds = (long)__gg__binary_value_from_qualified_field(&rdigits, + arg1, + arg1_o, + arg1_s); + tm.tm_hour = seconds/3600; + tm.tm_min = ((seconds%3600) / 60) % 100; + tm.tm_sec = seconds % 100; + strftime(ach, sizeof(ach), nl_langinfo(T_FMT), &tm); + } + + __gg__adjust_dest_size(dest, strlen(ach)); + ascii_to_internal_str(ach, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } diff --git a/libgcobol/io.cc b/libgcobol/io.cc new file mode 100644 index 00000000000..4dca42e0bad --- /dev/null +++ b/libgcobol/io.cc @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "io.h" +#include "stdio.h" +#include "stdlib.h" +#include +#include +#include + +/* + * The Cobol runtime support is responsible to set the file status + * word appropriately to the application's expectations. This function + * sets the defined file status register for the file to value of the + * status parameter, except for FhErrno. For FhErrno, it sets the + * file status register to a value derived from the current value of + * errno. If the errno value is not accounted for, the high bit is + * set to 1, and the rest to errno. + */ +extern "C" +file_status_t +__gg__file_status_word( enum file_status_t status, + int error_number) { + file_status_t file_status_register; + + if( status != FsErrno ) { + return status; + } + + switch( error_number ) { + case 0: file_status_register = FsSuccess; break; + case EACCES: file_status_register = FsNoAccess; break; + case EDQUOT: file_status_register = FsBoundary; break; + case EEXIST: file_status_register = FsNoAccess; break; + case EFAULT: file_status_register = FsNoFile; break; + case EFBIG: file_status_register = FsBoundary; break; + case EINTR: file_status_register = FsOsError; break; + case EINVAL: file_status_register = FsWrongType; break; + case EISDIR: file_status_register = FsWrongType; break; + case ELOOP: file_status_register = FsOsError; break; + case EMFILE: file_status_register = FsOsError; break; + case ENAMETOOLONG: + file_status_register = FsWrongType; break; + case ENFILE: file_status_register = FsOsError; break; + case ENODEV: file_status_register = FsNoFile; break; + case ENOENT: file_status_register = FsNoFile; break; + case ENOMEM: file_status_register = FsOsError; break; + case ENOSPC: file_status_register = FsBoundary; break; + case ENOTDIR: file_status_register = FsNoFile; break; + case ENXIO: file_status_register = FsNoFile; break; + case EOPNOTSUPP: + file_status_register = FsOsError; break; + case EOVERFLOW: file_status_register = FsBoundary; break; + case EPERM: file_status_register = FsNoAccess; break; + case EROFS: file_status_register = FsNoAccess; break; + case ETXTBSY: file_status_register= FsWrongType; break; + case EWOULDBLOCK: + file_status_register = FsOsError; break; + default: + perror("What is this? "); + fprintf(stderr, "__gg__file_status_word got an error_number " + "%d, which it doesn't know how to handle\n", error_number); + + abort(); + break; + } + + return file_status_register; +} diff --git a/libgcobol/io.h b/libgcobol/io.h new file mode 100644 index 00000000000..0c89ad6d0c9 --- /dev/null +++ b/libgcobol/io.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * File status key values and meanings + * 0 Successful completion + * 0 No further information + * 2 Duplicate key READ + * 4 Short/long READ + * 5 OPEN optional file unavailable + * 7 Not a tape + * 1 At-end condition + * 0 Sequential READ EOF + * 4 Relative record too big + * 2 Invalid key condition + * 1 Sequence error + * 2 Duplicate key WRITE + * 3 Record not found + * 4 Sequential WRITE EOF + * 3 Permanent error + * 0 No further information + * 1 Filename inconsistent with operating system + * 4 Boundary violation + * 5 OPEN nonoptional file unavailable + * 7 OPEN EACCES + * 8 OPEN file previously closed with lock + * 9 OPEN wrong file type + * 4 Logic error condition + * 1 OPEN file already open + * 2 CLOSE file not open + * 3 REWRITE without prior READ + * 4 REWRITE/WRITE boundary violation + * 6 READ after failed READ + * 7 File not open for READ + * 8 File not open for WRITE + * 9 File not open for DELETE/REWRITE + * 9 Implementor-defined + * 0 VSAM/QSAM close on wrong thread + * 1 VSAM password failure + * 2 Logic error + * 3 Resource unavailable + * 5 Incomplete file information + * 6 VSAM no DD statement + * 7 VSAM File integrity verified + * 8 OPEN invalid environment variable contents + */ + +#ifndef IO_H_ +#define IO_H_ + +enum file_high_t { + FhSuccess = 0, + FhAtEnd = 1, + FhInvKey = 2, + FhOsError = 3, + FhLogicError = 4, + FhImplementor = 9, +}; + +enum file_status_t { + FsSuccess = FhSuccess, + FsDupRead = (FhSuccess * 10) + 2, // First digit is 0 + FsRecordLength= (FhSuccess * 10) + 4, + FsUnavail = (FhSuccess * 10) + 5, + FsNotaTape = (FhSuccess * 10) + 7, + + FsEofSeq = (FhAtEnd * 10) + 0, // First digit is 1 + FsEofRel = (FhAtEnd * 10) + 4, + + FsKeySeq = (FhInvKey * 10) + 1, // First digit is 2 + FsDupWrite = (FhInvKey * 10) + 2, + FsNotFound = (FhInvKey * 10) + 3, + FsEofWrite = (FhInvKey * 10) + 4, + + FsOsError = (FhOsError * 10) + 0, // First digit is 3 + FsNameError = (FhOsError * 10) + 1, + FsBoundary = (FhOsError * 10) + 4, + FsNoFile = (FhOsError * 10) + 5, + FsNoAccess = (FhOsError * 10) + 7, + FsCloseLock = (FhOsError * 10) + 8, + FsWrongType = (FhOsError * 10) + 9, + + FsLogicErr = (FhLogicError * 10) + 0, // First digit is 4 + FsIsOpen = (FhLogicError * 10) + 1, + FsCloseNotOpen= (FhLogicError * 10) + 2, + FsNoRead = (FhLogicError * 10) + 3, + FsBoundWrite = (FhLogicError * 10) + 4, + FsReadError = (FhLogicError * 10) + 6, + FsReadNotOpen = (FhLogicError * 10) + 7, + FsNoWrite = (FhLogicError * 10) + 8, + FsNoDelete = (FhLogicError * 10) + 9, + + FsWrongThread = (FhImplementor * 10) + 0, // First digit is 9 + FsPassword = (FhImplementor * 10) + 1, + FsLogicOther = (FhImplementor * 10) + 2, + FsNoResource = (FhImplementor * 10) + 3, + FsIncomplete = (FhImplementor * 10) + 5, + FsNoDD = (FhImplementor * 10) + 6, + FsVsamOK = (FhImplementor * 10) + 7, + FsBadEnvVar = (FhImplementor * 10) + 8, + + FsErrno = (1000000) // This means "map errno to one of the above errors" +}; + +#define FhNotOkay FsEofSeq // Values less than 10 mean the data are valid + +extern "C" file_status_t __gg__file_status_word(enum file_status_t status, + int error_number); + +#endif diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc new file mode 100644 index 00000000000..0890835822c --- /dev/null +++ b/libgcobol/libgcobol.cc @@ -0,0 +1,12649 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "common-defs.h" +#include "io.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "gfileio.h" +#include "charmaps.h" +#include "valconv.h" + +#include +#include +#include + +#include + +#include "exceptl.h" + +// This couldn't be defined in symbols.h because it conflicts with a LEVEL66 +// in parse.h +#define LEVEL66 (66) +#define LEVEL88 (88) + +// These global variables are returned when the functions +// EXCEPTION-FILE +// EXCEPTION-LOCATION +// EXCEPTION-STATEMENT +// EXCEPTION-STATUS +// are called + +// These global values are established as the COBOL program executes +int __gg__exception_code = 0 ; +int __gg__exception_handled = 0 ; +int __gg__exception_file_number = 0 ; +int __gg__exception_file_status = 0 ; +const char *__gg__exception_file_name = NULL ; +const char *__gg__exception_program_id = NULL ; +const char *__gg__exception_section = NULL ; +const char *__gg__exception_paragraph = NULL ; +const char *__gg__exception_source_file = NULL ; +int __gg__exception_line_number = 0 ; +const char *__gg__exception_statement = NULL ; +int __gg__default_compute_error = 0 ; +int __gg__rdigits = 0 ; +int __gg__odo_violation = 0 ; +int __gg__nop = 0 ; +int __gg__main_called = 0 ; + +// What follows are arrays that are used by features like INSPECT, STRING, +// UNSTRING, and, particularly, arithmetic_operation. These features are +// characterized by having unknown, and essentially unlimited, numbers of +// variables. Consider, for example, ADD A B C D ... TO L M N O ... + +// Although originally implemented with malloc/free, that's terribly inefficient +// on its face; arithmetic is done frequently. The next step was to malloc +// buffers just once, and have them grow as needed, but that resulted in a lot +// of code being laid down, because it meant checking each buffer size at +// run-time, and laying down the code to be executed if the size was inadequate. +// +// The current solution is to make the pointers to the arrays of values global, +// and initialize them with space for MIN_FIELD_BLOCK_SIZE values. Thus, at +// compile time, we can ignore all tests for fewer than MIN_FIELD_BLOCK_SIZE +// (which is generally the case). Only when N is greater than the MIN do we +// have to check the current run-time size and, if necessary, expand the buffer +// with realloc. +size_t __gg__arithmetic_rounds_size = 0 ; +int * __gg__arithmetic_rounds = NULL ; + +size_t __gg__fourplet_flags_size = 0 ; +int * __gg__fourplet_flags = NULL ; + +static size_t treeplet_1_size = 0 ; +cblc_field_t ** __gg__treeplet_1f = NULL ; +size_t * __gg__treeplet_1o = NULL ; +size_t * __gg__treeplet_1s = NULL ; + +static size_t treeplet_2_size = 0 ; +cblc_field_t ** __gg__treeplet_2f = NULL ; +size_t * __gg__treeplet_2o = NULL ; +size_t * __gg__treeplet_2s = NULL ; + +static size_t treeplet_3_size = 0 ; +cblc_field_t ** __gg__treeplet_3f = NULL ; +size_t * __gg__treeplet_3o = NULL ; +size_t * __gg__treeplet_3s = NULL ; + +static size_t treeplet_4_size = 0 ; +cblc_field_t ** __gg__treeplet_4f = NULL ; +size_t * __gg__treeplet_4o = NULL ; +size_t * __gg__treeplet_4s = NULL ; + + +// This value is increased every time PROCEDURE DIVISION is processed. It is +// used to keep track of local variables. +size_t __gg__unique_prog_id = 0 ; + +// These values are the persistent stashed versions of the global values +static int stashed_exception_code; +static int stashed_exception_handled; +static int stashed_exception_file_number; +static int stashed_exception_file_status; +static const char *stashed_exception_file_name; +static const char *stashed_exception_program_id; +static const char *stashed_exception_section; +static const char *stashed_exception_paragraph; +static const char *stashed_exception_source_file; +static int stashed_exception_line_number; +static const char *stashed_exception_statement; + +static int sv_from_raise_statement = 0; + +typedef void (*PFUNC)(); +static std::unordered_map accessible_programs; +static std::unordered_map accessible_pointers; + +#define ARG_LIMIT 512 +char *__gg__call_parameter_signature = NULL; +int __gg__call_parameter_count = A_ZILLION; +size_t __gg__call_parameter_lengths[ARG_LIMIT]; + +// This is used for managing ENTRY statements in COBOL routines +void *__gg__entry_location = NULL; + +// This is the current value at the back of the PERFORM stack of +// procedure signatures. Said another way: When the exit address at +// the end of a paragraph matches this value address, then it is time to pop +// the return address off of the stack. It's in this fashion that we implements +// nested PERFORM PROC statements. +void *__gg__exit_address = NULL; + +static ec_status_t ec_status; + +static const ec_descr_t * +local_ec_type_descr( ec_type_t type ) { + auto p = std::find( __gg__exception_table, __gg__exception_table_end, type ); + if( p == __gg__exception_table_end ) + { + __gg__abort("Fell off the end of the __gg__exception_table"); + } + return p; +} + +static const char * +local_ec_type_str( ec_type_t type ) { + if( type == ec_none_e ) return "EC-NONE"; + auto p = local_ec_type_descr(type); + return p->name; +} + +ec_status_t& ec_status_t::update() { + handled = ec_type_t(__gg__exception_handled); + type = ec_type_t(__gg__exception_code); + __gg__exception_code = ec_none_e; + source_file = __gg__exception_source_file; + lineno = __gg__exception_line_number; + if( __gg__exception_statement ) { + snprintf(statement, sizeof(statement), "%s", __gg__exception_statement); + } + + if( type != ec_none_e && getenv("match_declarative") ) { + warnx( "ec_status_t::update:%d: EC %s by %s handled %02X " , __LINE__, + local_ec_type_str(type), + __gg__exception_statement? statement : "", + handled ); // might be file-status, not ec_type_t + } + + return *this; +} + +static cbl_truncation_mode truncation_mode = trunc_std_e; + +struct program_state + { + // These are the run-time values of these characters. + + // They are always in source_code space; they get converted to native + // when they are used. + int rt_decimal_point; + int rt_decimal_separator; + int rt_quote_character; + int rt_low_value_character; + int rt_high_value_character; + char *rt_currency_signs[256]; + const unsigned short *rt_collation; // Points to a table of 256 values; + char *rt_program_name; + + program_state() + { + // IBM defaults to the \" QUOTE compiler option. quote_character must + // be set to \' when the APOST compiler option is in effect + + // rt_currency_signs provides for replacing a PICTURE currency "symbol" + // with a character string referred to in the language specification as + // a "sign". The string can be an arbitrary length, allowing the + // replacement of, as an example, the currency "$" with the + // "USD" + + rt_decimal_point = ascii_period ; + rt_decimal_separator = ascii_comma ; + rt_quote_character = ascii_dquote ; // Change this with APOST + rt_low_value_character = DEGENERATE_LOW_VALUE ; + rt_high_value_character = DEGENERATE_HIGH_VALUE ; + + // Set all the currency_sign pointers to NULL: + + memset(rt_currency_signs, 0, sizeof(rt_currency_signs)); + + // The default collating sequence: + if( internal_is_ebcdic ) + { + rt_collation = __gg__cp1140_to_cp1252_values; + } + else + { + rt_collation = __gg__one_to_one_values; + } + rt_program_name = NULL; + } + + program_state(const program_state &ps) + { + rt_decimal_point = ps.rt_decimal_point ; + rt_decimal_separator = ps.rt_decimal_separator ; + rt_quote_character = ps.rt_quote_character ; + rt_low_value_character = ps.rt_low_value_character ; + // Note throughout the code that there is special processing for the + // high-value character. In EBCDIC 0xFF doesn't map to ASCII 0xFF, so + // we are forced to avoid converting EBCDIC 0xFF. + rt_high_value_character = ps.rt_high_value_character ; + rt_collation = ps.rt_collation ; + + for( int i=0; i<256; i++ ) + { + if( ps.rt_currency_signs[i] ) + { + rt_currency_signs[i] = strdup(ps.rt_currency_signs[i]); + } + else + { + rt_currency_signs[i] = NULL; + } + } + + rt_program_name = ps.rt_program_name ; + } + + ~program_state() + { + for(int symbol=0; symbol<256; symbol++) + { + if( rt_currency_signs[symbol] ) + { + free(rt_currency_signs[symbol]); + rt_currency_signs[symbol] = NULL; + } + } + } + }; + +static std::vector program_states; +#define collated(a) (program_states.back().rt_collation[(unsigned int)(a&0xFF)]) +#define program_name (program_states.back().rt_program_name) +// #define decimal_point (program_states.back().rt_decimal_point) +// #define decimal_separator (program_states.back().rt_decimal_separator) +// #define quote_character (program_states.back().rt_quote_character) +// #define low_value_character (program_states.back().rt_low_value_character) +// #define high_value_character (program_states.back().rt_high_value_character) +// #define currency_signs(a) (program_states.back().rt_currency_signs[(a)]) +#define currency_signs(a) (__gg__currency_signs[(a)]) + +#ifdef DEBUG_MALLOC +void *malloc(size_t a) + { + void *retval = malloc(a); + fprintf(stderr, " --malloc(%p)-- ", retval); + return retval; + return retval; + } +#endif + +void +__gg__abort(const char *msg) + { + fprintf(stderr, "%s: %s\n", program_name, msg); + abort(); + } + +extern "C" +char +__gg__get_decimal_point() + { + return __gg__decimal_point; + } + +extern "C" +char +__gg__get_decimal_separator() + { + return __gg__decimal_separator; + } + +extern "C" +char * +__gg__get_default_currency_string() + { + return currency_signs(__gg__default_currency_sign); + } + +extern "C" +void +__gg__resize_int_p( size_t *size, + int **block, + size_t new_size) + { + if( new_size > *size ) + { + *size = new_size; + *block = (int *)realloc(*block, new_size * sizeof(int)); + } + } + +extern "C" +void +__gg__resize_treeplet(int ngroup, + size_t new_size) + { + switch( ngroup ) + { + case 1: + if( new_size > treeplet_1_size ) + { + treeplet_1_size = new_size; + __gg__treeplet_1f = (cblc_field_t **)realloc(__gg__treeplet_1f, new_size * sizeof(cblc_field_t *)); + __gg__treeplet_1o = (size_t *)realloc(__gg__treeplet_1o, new_size * sizeof(size_t)); + __gg__treeplet_1s = (size_t *)realloc(__gg__treeplet_1s, new_size * sizeof(size_t)); + } + break; + case 2: + if( new_size > treeplet_2_size ) + { + treeplet_2_size = new_size; + __gg__treeplet_2f = (cblc_field_t **)realloc(__gg__treeplet_2f, new_size * sizeof(cblc_field_t *)); + __gg__treeplet_2o = (size_t *)realloc(__gg__treeplet_2o, new_size * sizeof(size_t)); + __gg__treeplet_2s = (size_t *)realloc(__gg__treeplet_2s, new_size * sizeof(size_t)); + } + break; + case 3: + if( new_size > treeplet_3_size ) + { + treeplet_3_size = new_size; + __gg__treeplet_3f = (cblc_field_t **)realloc(__gg__treeplet_3f, new_size * sizeof(cblc_field_t *)); + __gg__treeplet_3o = (size_t *)realloc(__gg__treeplet_3o, new_size * sizeof(size_t)); + __gg__treeplet_3s = (size_t *)realloc(__gg__treeplet_3s, new_size * sizeof(size_t)); + } + break; + case 4: + if( new_size > treeplet_4_size ) + { + treeplet_4_size = new_size; + __gg__treeplet_4f = (cblc_field_t **)realloc(__gg__treeplet_4f, new_size * sizeof(cblc_field_t *)); + __gg__treeplet_4o = (size_t *)realloc(__gg__treeplet_4o, new_size * sizeof(size_t)); + __gg__treeplet_4s = (size_t *)realloc(__gg__treeplet_4s, new_size * sizeof(size_t)); + } + break; + } + } + +static void +initialize_program_state() + { + // This routine gets called exactly once for a COBOL executable + program_state initial_value = {}; + program_states.push_back(initial_value); + __gg__currency_signs = program_states.back().rt_currency_signs; + + // This is where we initialize the various tables that have + // MIN_FIELD_BLOCK_SIZE elements: + + __gg__resize_int_p(&__gg__arithmetic_rounds_size, + &__gg__arithmetic_rounds, + MIN_FIELD_BLOCK_SIZE ); + __gg__resize_int_p(&__gg__fourplet_flags_size, + &__gg__fourplet_flags, + MIN_FIELD_BLOCK_SIZE ); + __gg__resize_treeplet(1, MIN_FIELD_BLOCK_SIZE); + __gg__resize_treeplet(2, MIN_FIELD_BLOCK_SIZE); + __gg__resize_treeplet(3, MIN_FIELD_BLOCK_SIZE); + __gg__resize_treeplet(4, MIN_FIELD_BLOCK_SIZE); + } + +extern "C" +void +__gg__set_program_name(char *progname) + { + program_name = progname; + } + +extern "C" +void +__gg__push_program_state() + { + // Duplicate the state at the back of the stack + program_states.push_back(program_states.back()); + __gg__currency_signs = program_states.back().rt_currency_signs; + } + +extern "C" +void +__gg__pop_program_state() + { + program_states.pop_back(); + +// #define decimal_point (program_states.back().rt_decimal_point) +// #define decimal_separator (program_states.back().rt_decimal_separator) +// #define quote_character (program_states.back().rt_quote_character) +// #define low_value_character (program_states.back().rt_low_value_character) +// #define high_value_character (program_states.back().rt_high_value_character) + + __gg__decimal_point = program_states.back().rt_decimal_point ; + __gg__decimal_separator = program_states.back().rt_decimal_separator ; + __gg__quote_character = program_states.back().rt_quote_character ; + __gg__low_value_character = program_states.back().rt_low_value_character ; + __gg__high_value_character = program_states.back().rt_high_value_character ; + __gg__currency_signs = program_states.back().rt_currency_signs ; + +} + +static +int +cstrncmp( char const * const left_, + char const * const right_, + size_t count) + { + const char *left = left_; + const char *right = right_; + // This is the version of strncmp() that uses the current collation + + // It also is designed to handle strings with embedded NUL characters, so + // it treats NULs like any other characters. + int retval = 0; + while( count-- ) + { + unsigned char chl = *left++; + unsigned char chr = *right++; + retval = chl - chr; + if( retval ) + { + break; + } + } + return retval; + } + +extern "C" +void +__gg__decimal_point_is_comma() + { + program_states.back().rt_decimal_point = ascii_comma ; + program_states.back().rt_decimal_separator = ascii_period ; + __gg__decimal_point = ascii_comma ; + __gg__decimal_separator = ascii_period ; + } + +extern "C" +void +__gg__init_program_state() + { + // This routine gets called at DATA DIVISION time. + + // We need to make sure that the program_states vector has at least one + // entry in it. This happens when we are the very first PROGRAM-ID called + // in this module. + if( program_states.empty() ) + { + initialize_program_state(); + } + } + +static int +var_is_refmod( cblc_field_t *var ) + { + return (var->attr & refmod_e) != 0; + } + +extern "C" +__int128 +__gg__power_of_ten(int n) + { + // 2** 64 = 1.8E19 + // 2**128 = 3.4E38 + __int128 retval = 1; + static const int MAX_POWER = 19 ; + static const __int128 pos[MAX_POWER+1] = + { + 1ULL, // 00 + 10ULL, // 01 + 100ULL, // 02 + 1000ULL, // 03 + 10000ULL, // 04 + 100000ULL, // 05 + 1000000ULL, // 06 + 10000000ULL, // 07 + 100000000ULL, // 08 + 1000000000ULL, // 09 + 10000000000ULL, // 10 + 100000000000ULL, // 11 + 1000000000000ULL, // 12 + 10000000000000ULL, // 13 + 100000000000000ULL, // 14 + 1000000000000000ULL, // 15 + 10000000000000000ULL, // 16 + 100000000000000000ULL, // 17 + 1000000000000000000ULL, // 18 + 10000000000000000000ULL, // 19 + }; + if( n < 0 || n>MAX_POWER*2) // The most we can handle is 10**38 + { + fprintf(stderr, + "Trying to raise 10 to %d as an int128, which we can't do.\n", + n); + fprintf(stderr, "The problem is in %s.\n", __func__); + abort(); + } + if( n <= MAX_POWER ) + { + // Up to 10**18 we do directly: + retval = pos[n]; + } + else + { + // 19 through 38: + retval = pos[n/2]; + retval *= retval; + if( n & 1 ) + { + retval *= 10; + } + } + return retval; + } + +extern "C" +__int128 +__gg__scale_by_power_of_ten_1(__int128 value, int N) + { + // This routine is called when the result of the scaling is not allowed to + // have non-zero rdigits. __gg__rdigits is set to 1 when the result is + // in the bad zone. The ultimate caller needs to examine __gg__rdigits to + // decide what to do about it. + + // This is a separate routine because of the performance hit caused by the + // value % pot operation, which is needed only when certain EC checking is + // turned on. + if( N > 0 ) + { + __gg__rdigits = 0; + value *= __gg__power_of_ten(N); + } + else if( N < 0) + { + // We throwing away the N rightmost digits. Use __gg__rdigits + // to let the calling chain know they were non-zero: + __int128 pot = __gg__power_of_ten(-N); + if( value % pot) + { + __gg__rdigits = 1; + } + else + { + __gg__rdigits = 0; + } + + value /= pot; + } + else + { + // N is zero + __gg__rdigits = 0; + } + return value; + } + +extern "C" +__int128 +__gg__scale_by_power_of_ten_2(__int128 value, int N) + { + if( N > 0 ) + { + value *= __gg__power_of_ten(N); + } + else if( N < 0) + { + value /= __gg__power_of_ten(-N); + } + return value; + } + +extern "C" +bool +__gg__binary_to_string(char *result, int digits, __int128 value) + { + // The result is not terminated, because this routine is used + // to put information directly into cblc_field_t::data + // Our caller has to keep track of whether value was negative. + + // Note that this routine operates in the source code-set space; that is + // the result comes back with zero as an ASCII 0x30, not an EBCDIC 0xF0 + + if( value < 0 ) + { + value = -value; + } + result += digits-1 ; + while( digits-- ) + { + *result-- = value%10 + ascii_zero; + value /= 10; + } + // Should value be non-zero, it means we potentially have a size error + return value != 0; + } + +extern "C" +bool +__gg__binary_to_string_internal(char *result, int digits, __int128 value) + { + // The result is not terminated, because this routine is used + // to put information directly into cblc_field_t::data + // Our caller has to keep track of whether value was negative. + + // Note that this routine operates in the source code-set space; that is + // the result comes back with zero as an ASCII 0x30, not an EBCDIC 0xF0 + + if( value < 0 ) + { + value = -value; + } + result += digits-1 ; + while( digits-- ) + { + *result-- = (value%10) + internal_zero; + value /= 10; + } + // Should value be non-zero, it means we potentially have a size error + return value != 0; + } + +static bool +value_is_too_big( cblc_field_t *var, + __int128 value, + int source_rdigits) + { + // This routine is in support of arithmetic ON SIZE ERROR. It returns + // TRUE if var hasn't enough bytes to hold the decimal representation + // of value: + bool retval = false; + + if( !(var->attr & intermediate_e) ) + { + if( value < 0 ) + { + value = -value; + } + if( var->digits ) + { + // I don't know how to describe this calculation. I came up with the + // equation by working a few examples. For instance, if value is 12345 and + // source_rdigits is two, then we are trying to cram 123.45 into 99v99999 + // and we have a size error. So, digits is 7, rdigits is 5 and source_rdigits + // 2. That means we compare 12345 with 10^(7 - 5 + 2), which is 12345 versus + // 10000, which is too big, which means we have a size error. + retval = + value >= __gg__power_of_ten( var->digits - var->rdigits + source_rdigits); + } + else + { + // var->digits is zero. We are dealing with a binary-style number that + // fills the whole of the value + if( !( var->type == FldNumericBin5 + || var->type == FldPointer + || var->type == FldIndex) ) + { + __gg__abort("value_is_too_big() was given a type it doesn't know about"); + } + if( var->capacity < 16 ) + { + __int128 max_possible = 1; + max_possible = max_possible << (var->capacity * 8); + retval = value >= max_possible; + } + } + } + + return retval; + } + +static void +binary_to_big_endian( unsigned char *dest, + int bytes, + __int128 value + ) + { + if( value < 0 ) + { + memset(dest, 0xFF, bytes); + } + else + { + memset(dest, 0x00, bytes); + } + + dest += bytes-1; + while( bytes-- ) + { + *dest-- = (unsigned char) value; + value >>= 8; + } + } + +static void +binary_to_little_endian( unsigned char *dest, + int bytes, + __int128 value + ) + { + if( value < 0 ) + { + memset(dest, 0xFF, bytes); + } + else + { + memset(dest, 0x00, bytes); + } + memcpy(dest, &value, bytes); + } + +static void +turn_sign_bit_on(unsigned char *location) + { + if( internal_is_ebcdic ) + { + *location &= ~NUMERIC_DISPLAY_SIGN_BIT; + } + else + { + *location |= NUMERIC_DISPLAY_SIGN_BIT; + } + } + +static void +turn_sign_bit_off(unsigned char *location) + { + if( internal_is_ebcdic ) + { + *location |= NUMERIC_DISPLAY_SIGN_BIT; + } + else + { + *location &= ~NUMERIC_DISPLAY_SIGN_BIT; + } + } + +static bool +is_sign_bit_on(char ch) + { + bool retval; + if( (unsigned char)ch == 0xFF || ch == 0x00 ) + { + // Don't let HIGH-VALUE or LOW_VALUE confuse sign detection + retval = false; + } + else + { + if( internal_is_ebcdic ) + { + retval = (ch & NUMERIC_DISPLAY_SIGN_BIT) == 0; + } + else + { + retval = (ch & NUMERIC_DISPLAY_SIGN_BIT) != 0; + } + } + return retval; + } + +extern "C" +void +__gg__string_to_alpha_edited_ascii( char *dest, + char *source, + int slength, + char *picture) + { + char *dupe = (char *)malloc(slength); + memcpy(dupe, source, slength); + ascii_to_internal_str(dupe, slength); + __gg__string_to_alpha_edited(dest, dupe, slength, picture); + free(dupe); + } + +static __int128 +int128_to_int128_rounded( cbl_round_t rounded, + __int128 value, + __int128 factor, + __int128 remainder, + int *compute_error) + { + // value is signed, and is scaled to the target + _Float128 fpart = _Float128(remainder) / _Float128(factor); + __int128 retval = value; + + if(rounded == nearest_even_e && fpart != -0.5Q && fpart != 0.5Q ) + { + // "bankers rounding" has been requested. + // + // Since the fraction is not 0.5, this is an ordinary rounding + // problem + rounded = nearest_away_from_zero_e; + } + + switch(rounded) + { + case truncation_e: + break; + + case nearest_away_from_zero_e: + { + // This is ordinary rounding, like you learned in grade school + // 0.0 through 0.4 becomes 0 + // 0.5 through 0.9 becomes 1 + if( value < 0 ) + { + if( fpart <= -0.5Q ) + { + retval -= 1; + } + } + else + { + if( fpart >= 0.5Q ) + { + retval += 1; + } + } + break; + } + + case away_from_zero_e: + { + // zero stays zero, otherwise head for the next number away from zero + if( value < 0 ) + { + if( fpart != 0 ) + { + retval -= 1; + } + } + else + { + if( fpart != 0 ) + { + retval += 1; + } + } + break; + } + + case nearest_toward_zero_e: + { + // 0.0 through 0.5 becomes 0 + // 0.6 through 0.9 becomes 1 + if( value < 0 ) + { + if( fpart < -0.5Q ) + { + retval -= 1; + } + } + else + { + if( fpart > 0.5Q ) + { + retval += 1; + } + } + break; + } + + case toward_greater_e: + { + if( value > 0 ) + { + if( fpart != 0 ) + { + retval += 1; + } + } + break; + } + + case toward_lesser_e: + { + if( value < 0 ) + { + if(fpart != 0) + { + retval -= 1; + } + } + break; + } + + case nearest_even_e: + { + // This is "banker's rounding" + // 3.4 -> 3.0 + // 3.5 -> 4.0 + // 3.6 -> 4.0 + + // 4.4 -> 4.0 + // 4.5 -> 4.0 + // 4.6 -> 5.0 + + // We know that the fractional part is 0.5 or -0.5, and we know that + // we want 3 to become 4 and for 4 to stay 4. + + if( value < 0 ) + { + if( retval & 1 ) + { + retval -= 1; + } + } + else + { + if( retval & 1 ) + { + retval += 1; + } + } + break; + } + + case prohibited_e: + { + if( fpart != 0 ) + { + *compute_error |= compute_error_truncate; + } + + break; + } + + default: + abort(); + break; + } + return retval; + } + +static __int128 +f128_to_i128_rounded( cbl_round_t rounded, + _Float128 value, + int *compute_error) + { + // value is signed, and is scaled to the target + _Float128 ipart; + _Float128 fpart = modff128(value, &ipart); + __int128 retval = (__int128)ipart; + + if(rounded == nearest_even_e && fpart != -0.5Q && fpart != 0.5Q ) + { + // "bankers rounding" has been requested. + // + // Since the fraction is not 0.5, this is an ordinary rounding + // problem + rounded = nearest_away_from_zero_e; + } + + switch(rounded) + { + case truncation_e: + break; + + case nearest_away_from_zero_e: + { + // This is ordinary rounding, like you learned in grade school + // 0.0 through 0.4 becomes 0 + // 0.5 through 0.9 becomes 1 + if( value < 0 ) + { + if( fpart <= -0.5Q ) + { + retval -= 1; + } + } + else + { + if( fpart >= 0.5Q ) + { + retval += 1; + } + } + break; + } + + case away_from_zero_e: + { + // zero stays zero, otherwise head for the next number away from zero + if( value < 0 ) + { + if( fpart != 0 ) + { + retval -= 1; + } + } + else + { + if( fpart != 0 ) + { + retval += 1; + } + } + break; + } + + case nearest_toward_zero_e: + { + // 0.0 through 0.5 becomes 0 + // 0.6 through 0.9 becomes 1 + if( value < 0 ) + { + if( fpart < -0.5Q ) + { + retval -= 1; + } + } + else + { + if( fpart > 0.5Q ) + { + retval += 1; + } + } + break; + } + + case toward_greater_e: + { + if( value > 0 ) + { + if( fpart != 0 ) + { + retval += 1; + } + } + break; + } + + case toward_lesser_e: + { + if( value < 0 ) + { + if(fpart != 0) + { + retval -= 1; + } + } + break; + } + + case nearest_even_e: + { + // This is "banker's rounding" + // 3.4 -> 3.0 + // 3.5 -> 4.0 + // 3.6 -> 4.0 + + // 4.4 -> 4.0 + // 4.5 -> 4.0 + // 4.6 -> 5.0 + + // We know that the fractional part is 0.5 or -0.5, and we know that + // we want 3 to become 4 and for 4 to stay 4. + + if( value < 0 ) + { + if( retval & 1 ) + { + retval -= 1; + } + } + else + { + if( retval & 1 ) + { + retval += 1; + } + } + break; + } + + case prohibited_e: + { + if( fpart != 0 ) + { + *compute_error |= compute_error_truncate; + } + + break; + } + + default: + abort(); + break; + } + return retval; + } + +static void +int128_to_field(cblc_field_t *var, + unsigned char *location, + size_t length, + __int128 value, + int source_rdigits, + enum cbl_round_t rounded, + int *compute_error) + { + // This routine takes a numerical value, and scales and converts it to the + // target field type. + + // It operates in the source codeset space, and converts the final result + // to the native codeset space + + switch( var->type ) + { + case FldFloat: + { + switch( var->capacity ) + { + case 4: + { + float tvalue = (float)value; + tvalue /= (float)__gg__power_of_ten(source_rdigits); + *(float *)location = tvalue; + break; + } + + case 8: + { + double tvalue = (double)value; + tvalue /= (double)__gg__power_of_ten(source_rdigits); + *(double *)location = tvalue; + break; + } + + case 16: + { + // It turns out we have a problem. The IEEE 754 quadruple-precision + // binary representation can handle up to 33 digits exactly, and can + // handle at most 36 digits. I decided to implement fixed-point + // values to 38 places (which is what an __int128 can hold), and as a + // result, at this point in the code we can be asking the compiler to + // turn a 38-digit __int128 into a _Float128. + + // This caused a problem that I noticed in COMPUTE var = (2/3)*3. + + // The default is truncation, and so the PIC 9V9999 result should be + // 1.9999. + + // At this point in the code, the 128-bit value was the + // 38-digit 19999999999999999999999999999999999998 + + // So, I then converted that to a _Float128, and the conversion + // routine properly did the best it could and returned exactly + // 2E37 + + // The problem: This rounded the number up from 1.9999...., and so + // the truncation resulted in 2.0000 when we wanted 1.9999 + + // The solution: Throw away digits on the right to make sure there + // are no more than 33 significant digits. + + bool isneg = value < 0; + if(isneg) + { + value = -value; + } + + static __int128 ten33 = __gg__power_of_ten(33); + + while( value >= ten33 ) + { + // Lop off the rightmost digits until the result has no more than + // 33 digits. + value /= 10; + source_rdigits -= 1; + } + + if(isneg) + { + value = -value; + } + _Float128 tvalue = (_Float128 )value; + tvalue /= (_Float128 )__gg__power_of_ten(source_rdigits); + // *(_Float128 *)location = tvalue; + // memcpy because *(_Float128 *) requires a 16-byte boundary. + memcpy(location, &tvalue, 16); + break; + } + } + break; + } + + default: + { + bool size_error = false; + + int target_rdigits = var->rdigits; + if( var->attr & intermediate_e && var->type == FldNumericBin5) + { + // The target is an intermediate, meaning that we want to + // Make sure our intermediate target has just enough digits and rdigits + // to hold the value we've been given: + target_rdigits = source_rdigits; + var->rdigits = target_rdigits; + var->digits = MAX_FIXED_POINT_DIGITS; + } + else if( var->attr & scaled_e ) + { + // Our target is scaled. No matter which way we are going, the result + // going into memory has no decimal places. + target_rdigits = 0; + + // We have some additional scaling of value to do to make things line up. + + if( var->rdigits >= 0 ) + { + // Our target is something like PPPPPP999, meaning that var->actual_length + // is 3, and var->rdigits is 6. + + // By rights, our caller should have given us something like 123 with + // source_rdigits of 9. So, we multiply by 10**9 to put the 123 just + // to the left of the decimal point, so that they line up with the + // target_rdigits of zero we are targeting: + source_rdigits -= var->digits + var->rdigits; + if(source_rdigits < 0) + { + // We overshot + value *= __gg__power_of_ten(-source_rdigits); + source_rdigits = 0; + } + } + else + { + // Our target is something like 999PPPPPP, so there is a ->digits + // of 3 and var->rdigits of -6. + + // If our caller gave us 123000000, we need to effectively divide + // it by 1000000 to line up the 123 with where we want it to go: + + source_rdigits += (-var->rdigits); + } + // Either way, we now have everything aligned for the remainder of the + // processing to work: + } + + // Convert the scale of value to match the scale of var + if( source_rdigits < target_rdigits ) + { + // The source (value), has fewer rdigits than the target (var) + + // Multiply value by ten until the source_rdigits matches the + // target_rdigits. No rounding will be necessary + value *= __gg__power_of_ten(target_rdigits - source_rdigits); + source_rdigits = target_rdigits; + } + + if( source_rdigits > target_rdigits ) + { + // The source(value) has more rdigits than the target (var) + + // Extract those extra digits; we'll need them for rounding: + __int128 factor = __gg__power_of_ten(source_rdigits - target_rdigits); + + __int128 remainder = value % factor; + value /= factor; + source_rdigits = target_rdigits; + + value = int128_to_int128_rounded( rounded, + value, + factor, + remainder, + compute_error); + } + + // The documentation for ROUNDED MODE PHOHIBITED says that if the value + // doesn't fit into the target, "...the content of the resultant + // identifier is unchanged" + + if( compute_error && *compute_error && rounded == prohibited_e ) + { + // This is the case where we are not supposed to do anything + } + else + { + // Value is now scaled to the target's target_rdigits + + int is_negative = value < 0 ; + + if( !(var->attr & signable_e) && is_negative ) + { + if(false) + { + // I believe the COBOL spec allows for throwing INCOMPATIBLE-DATA + // errors. + printf( "runtime exception: assigning negative " + "value to unsigned variable %s\n", + var->name); + } + // Take the absolute value of value + value = -value; + is_negative = false; + } + + // And now we put value where it belongs + switch( var->type ) + { + case FldGroup: + case FldAlphanumeric: + // This is sort of a Hail Mary play. We aren't supposed to do this + // conversion if rdigits is non-zero. But we shouldn't have gotten + // here if rdigits is non-zero. So, we'll just go with the flow. + + // Note that sending a signed value to an alphanumeric strips off + // any plus or minus signs. + size_error = __gg__binary_to_string_internal( (char *)location, + length, value); + break; + + case FldNumericDisplay: + if( var->attr & signable_e ) + { + // Things get exciting when a numeric-display value is signable + + if( var->attr & separate_e ) + { + // Whether positive or negative, a sign there will be: + char sign_ch = is_negative ? internal_minus : internal_plus ; + if( var->attr & leading_e ) + { + // The sign character goes into the first location + size_error = + __gg__binary_to_string_internal((char *)(location+1), + length-1, value); + location[0] = sign_ch; + } + else + { + // The sign character goes into the last location + size_error = + __gg__binary_to_string_internal( (char *)location, + length-1, value); + location[length-1] = sign_ch; + } + } + else + { + // The sign information is not separate, so we put it into + // the number + size_error = + __gg__binary_to_string_internal(( char *)location, + length, value); + + if( size_error && is_negative ) + { + // If all of the digits are zero, then the result is zero, and + // we have to kill the is_negative flag: + is_negative = false; + for(size_t i=0; iattr & leading_e ) + { + // The sign bit goes into the first digit: + turn_sign_bit_on(&location[0]); + } + else + { + // The sign bit goes into the last digit: + turn_sign_bit_on(&location[length-1]); + } + } + } + } + else + { + // It's a simple positive number + size_error = __gg__binary_to_string_internal( (char *)location, + length, value); + } + + break; + + case FldNumericEdited: + { + if( value == 0 && (var->attr & blank_zero_e) ) + { + memset(location, internal_space, length); + } + else + { + char ach[512]; + + // At this point, value is scaled to the target's rdigits + + size_error = __gg__binary_to_string(ach, var->digits, value); + ach[var->digits] = NULLCH; + + // Convert that string according to the PICTURE clause + size_error |= __gg__string_to_numeric_edited( + (char *)location, + ach, + target_rdigits, + is_negative, + var->picture); + ascii_to_internal_str((char *)location, var->capacity); + } + + break; + } + + case FldNumericBinary: + binary_to_big_endian( location, + length, + value); + size_error = value_is_too_big(var, value, source_rdigits); + break; + + case FldNumericBin5: + case FldIndex: + case FldLiteralN: + case FldPointer: + // Weirdly, this might be a figurative constant, hopefully usually + // ZERO. Everything but HIGH-VALUE will end up zero. HIGH-VALUE + // will become one, but it is, apparently harmless. The HIGH-VALUE + // must get processed separately elsewhere. As the author, it would + // be nice if I knew -- but I don't. + binary_to_little_endian(location, + length, + value); + size_error = value_is_too_big(var, value, source_rdigits); + break; + + case FldAlphaEdited: + { + char ach[128]; + size_error = __gg__binary_to_string(ach, length, value); + ach[length] = NULLCH; + + // Convert that string according to the PICTURE clause + __gg__string_to_alpha_edited( + (char *)location, + ach, + strlen(ach), + var->picture); + break; + } + + case FldPacked: + { + static const unsigned char bin2pd[100] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + } ; + + // Convert the binary value to packed decimal. + + // Set the destination bytes to zero + memset(location, 0, length); + unsigned char sign_nybble = 0; + if( !(var->attr & packed_no_sign_e) ) + { + // This is COMP-3 packed decimal, so we need to make room to the + // right of the final decimal digit for the sign nybble: + value *= 10; + // Figure out what the sign nybble is going to be, and make the + // the value positive: + if(var->attr & signable_e) + { + if(value < 0) + { + sign_nybble = 0x0D; + value = -value; + } + else + { + sign_nybble = 0x0C; + } + } + else + { + sign_nybble = 0x0F; + if(value < 0) + { + value = -value; + } + } + } + // ploc points to the current rightmost byte of the location: + unsigned char *ploc = location + length -1 ; + + // Build the target from right to left, so that the result is + // big-endian: + while( value && ploc >= location ) + { + *ploc-- = bin2pd[value%100]; + value /= 100; + } + + // We can put the sign nybble into place at this point. Note that + // for COMP-6 numbers the sign_nybble value is zero, so the next + // operation is harmless. + location[length -1] |= sign_nybble; + + // If we still have value left, we have a size error + if( value ) + { + size_error = true; + } + else + { + if( ( sign_nybble && !(var->digits&1) ) + || ( !sign_nybble && (var->digits&1) ) ) + { + // This is either + // comp-3 with an even number of digits, or + // comp-6 with an odd number of digits. + // Either way, the first byte of the target has to have a high + // nybble of zero. If it's non-zero, then we have a size error: + if( location[0] & 0xF0 ) + { + size_error = true; + } + } + } + // And we're done. + break; + } + + default: + fprintf(stderr, "can't convert in %s() %s %d\n", + __func__, + var->name, + var->type); + abort(); + break; + } + if( compute_error ) + { + *compute_error |= size_error ? compute_error_truncate : 0; + } + } + } + break; + } + } + +static __int128 +edited_to_binary( const char *ps_, + int length, + int *rdigits) + { + const unsigned char *ps = (const unsigned char *)ps_; + // This routine is used for converting NumericEdited strings to + // binary. + + // Numeric edited strings can have all kinds of crap in them: spaces, + // slashes, dollar signs...you name it. It might have a minus sign at + // the beginning or end, or it might have CR or DB at the end. + + // We are going to look for a minus sign, D (or d) and use that to flag the + // result as negative. We are going to look for a decimal point and count up + // the numerical digits to the right of it. And we are going to pretend + // that nothing else matters. + + int hyphen = 0; + *rdigits = 0; + + // index into the ps string + int index = 0; + + // Create a delta_r for counting digits to the right of + // any decimal point. If and when we encounter a decimal point, + // we'll set this to one, otherwise it'll stay zero. + int delta_r = 0; + + __int128 result = 0; + + unsigned char ch; + + // We need to check the last two characters. If CR or DB, then the result + // is negative: + if( length >= 2) + { + if(((ps[length-2]&0xFF) == internal_D || (ps[length-2]&0xFF) == internal_d ) + &&((ps[length-1]&0xFF) == internal_B || (ps[length-1]&0xFF) == internal_b)) + { + hyphen = 1; + } + else if( ((ps[length-2]&0xFF) == internal_C + || (ps[length-2]&0xFF) == internal_c) + && ((ps[length-1]&0xFF) == internal_R + || (ps[length-1]&0xFF) == internal_r) ) + { + hyphen = 1; + } + } + + while( index < length ) + { + ch = ps[index++] & 0xFF; + if( ch == ascii_to_internal(__gg__decimal_point) ) + { + delta_r = 1; + continue; + } + if( ch == internal_minus ) + { + hyphen = 1; + continue; + } + + if( internal_0 <= ch && ch <= internal_9 ) + { + result *= 10; + // In both EBCDIC and ASCII, this works: + result += ch & 0x0F ; + *rdigits += delta_r ; + continue; + } + } + + if( result == 0 ) + { + hyphen = 0; + } + else if( hyphen ) + { + result = -result; + } + return result; + } + +static +__int128 +big_endian_to_binary_signed( + const unsigned char *psource, + int capacity +) + { + // This subroutine takes a big-endian value of "capacity" bytes and + // converts it to a signed INT128. The highest order bit of the big-endian + // value determines whether or not the highest-order bits of the INT128 + // return value are off or on. + + __int128 retval; + if( *psource >= 128 ) + { + retval = -1; + } + else + { + retval = 0; + } + + // move the bytes of psource into retval, flipping them end-to-end + unsigned char *dest = (unsigned char *)&retval; + while(capacity > 0) + { + *dest++ = psource[--capacity]; + } + return retval; + } + +static +__int128 +little_endian_to_binary_signed( + const unsigned char *psource, + int capacity +) + { + // This subroutine takes a little-endian value of "capacity" bytes and + // converts it to a signed INT128. The highest order bit of the little-endian + // value determines whether or not the highest-order bits of the INT128 + // return value are off or on. + + __int128 result; + + // Set all the bits of the result based on the sign of the source: + if( psource[capacity-1] >= 128 ) + { + result = -1; + } + else + { + result = 0; + } + + // Copy the low-order bytes into place: + memcpy(&result, psource, capacity); + return result; + } + +static +__int128 +little_endian_to_binary_unsigned( + const unsigned char *psource, + int capacity +) + { + __int128 result = 0; + + // Copy the low-order bytes into place: + memcpy(&result, psource, capacity); + return result; + } + +static +__int128 +big_endian_to_binary_unsigned( + const unsigned char *psource, + int capacity +) + { + // This subroutine takes an unsigned big-endian value of "capacity" bytes and + // converts it to an INT128. + + __int128 retval = 0 ; + + // move the bytes of psource into retval, flipping them end-to-end + unsigned char *dest = (unsigned char *)&retval; + while(capacity > 0) + { + *dest++ = psource[--capacity]; + } + return retval; + } + +static +__int128 +get_binary_value_local( int *rdigits, + cblc_field_t *resolved_var, + unsigned char *resolved_location, + size_t resolved_length) + { + __int128 retval = 0; + + unsigned char ch; + switch( resolved_var->type ) + { +#if 1 + case FldLiteralA : + fprintf(stderr, "%s(): is trying to handle a FldLiteralA\n", __func__); + abort(); + // // Read the data area as a dirty string: + // retval = __gg__dirty_to_binary_internal( (const char *)resolved_location, + // resolved_length, + // rdigits ); + break; +#endif + + case FldGroup : + case FldAlphanumeric : + // Read the data area as a dirty string: + retval = __gg__dirty_to_binary_internal( (const char *)resolved_location, + resolved_length, + rdigits ); + break; + + case FldNumericDisplay : + if( resolved_location[resolved_length-1] == DEGENERATE_HIGH_VALUE ) + { + // This is a degenerate case, which violates the language + // specification, but nonetheless seems to be a thing. By + // default, HIGH-VALUE is usually assumed to be 0xFF. This is + // not necessarily true; HIGH-VALUE can be changed by the + // SPECIAL-NAMES ALPHABET clause. Furthermore, by definition, + // HIGH-VALUE applies *only* to text literals. However, there + // seems to be code out in the universe that wants to be able + // to compare NumericDisplay values that have been set to + // HIGH-VALUE. Consider, for example, code that reads from + // a disk file which sets the input field to HIGH-VALUE upon + // an end-of-file condition. + + // This code detects that particular condition, and sets the + // resulting binary number to the maximum possible positive + // value. + + // Turn all the bits on + memset( &retval, 0xFF, sizeof(retval) ); + + // Make it positive + ((unsigned char *)&retval)[sizeof(retval)-1] = 0x3F; + *rdigits = resolved_var->rdigits; + } + else + { + // Pick up the sign byte, and force our value to be positive + unsigned char *sign_byte_location; + if( (resolved_var->attr & separate_e ) + && (resolved_var->attr & leading_e ) ) + { + sign_byte_location = resolved_location; + ch = *sign_byte_location; + *sign_byte_location = internal_plus; + } + else if( (resolved_var->attr & separate_e) + && !(resolved_var->attr & leading_e ) ) + { + sign_byte_location = resolved_location + resolved_length - 1; + ch = *sign_byte_location; + *sign_byte_location = internal_plus; + } + else if( (resolved_var->attr & leading_e) ) + { + sign_byte_location = resolved_location; + ch = *sign_byte_location; + turn_sign_bit_off(sign_byte_location); + } + else // if( !(resolved_var->attr & leading_e) ) + { + sign_byte_location = resolved_location + resolved_length - 1; + ch = *sign_byte_location; + turn_sign_bit_off(sign_byte_location); + } + + // We know where the decimal point is because of rdigits. Because + // we know that it a clean string of ASCII digits, we can use the + // dirty converter: + retval = __gg__dirty_to_binary_internal((const char *)resolved_location, + resolved_length, + rdigits ); + *rdigits = resolved_var->rdigits; + + // Restore the sign byte + *sign_byte_location = ch; + + if( ch == internal_minus || is_sign_bit_on(ch) ) + { + retval = -retval; + } + } + break; + + case FldNumericEdited : + retval = edited_to_binary( (const char *)resolved_location, + resolved_length, + rdigits); + break; + + case FldNumericBinary : + if( resolved_var->attr & signable_e) + { + retval = big_endian_to_binary_signed( + (const unsigned char *)resolved_location, + resolved_length); + } + else + { + retval = big_endian_to_binary_unsigned( + (const unsigned char *)resolved_location, + resolved_length); + } + *rdigits = resolved_var->rdigits; + break; + + case FldLiteralN: + { + if( resolved_var->attr & signable_e) + { + retval = little_endian_to_binary_signed(resolved_var->data, + resolved_var->capacity); + } + else + { + retval = little_endian_to_binary_unsigned(resolved_var->data, + resolved_var->capacity); + } + *rdigits = resolved_var->rdigits; + break; + } + + case FldNumericBin5: + case FldIndex: + case FldPointer: + if( resolved_var->attr & signable_e) + { + retval = little_endian_to_binary_signed( + (const unsigned char *)resolved_location, + resolved_length); + } + else + { + retval = little_endian_to_binary_unsigned( + (const unsigned char *)resolved_location, + resolved_length); + } + *rdigits = resolved_var->rdigits; + break; + + case FldPacked: + { + static const unsigned char dp2bin[160] = + { + // This may not be the weirdest table I've ever created, but it is + // certainly a contender. Given the packed decimal byte 0x23, it + // returns the equivalent decimal value of 23. + 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, 0, 0, 0, 0, 0, 0, // 0x00 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, // 0x10 + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, // 0x20 + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, // 0x30 + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0, // 0x40 + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0, // 0x50 + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0, // 0x60 + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, // 0x70 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, // 0x80 + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 0, 0, 0, 0, 0, 0, // 0x90 + }; + + if( resolved_var->attr & packed_no_sign_e ) + { + // This is packed decimal without a sign nybble + retval = 0; + for(size_t i=0; icapacity; i++) + { + retval *= 100; + retval += dp2bin[resolved_location[i]]; + } + } + else + { + // This is packed decimal with a final sign nybble + retval = 0; + size_t imputed_length = (resolved_var->digits + 2)/2; + for(size_t i=0; i>4; + if( (resolved_location[imputed_length-1]&0x0F) == 0x0D + || (resolved_location[imputed_length-1]&0x0F) == 0x0B ) + { + retval = -retval; + } + } + *rdigits = resolved_var->rdigits; + break; + } + } + + if( resolved_var->attr & scaled_e ) + { + // Here's where we handle a P-scaled number. + + if( resolved_var->rdigits >= 0) + { + // We might be dealing with a source with a PICTURE string of + // PPPPPP999, which means retval is a three-digit number + // and resolved_var->rdigits is +6. That means we need to divide retval + // by 10**9, and we need to make rdigits 9 + *rdigits = resolved_var->digits + resolved_var->rdigits; + } + else + { + // We have a source with a PIC string like 999PPPPPP, which is + // a capacity of 3 and a resolved_var->rdigits of -6. We need to multiply + // retval by +6, and make rdigits zero: + retval *= __gg__power_of_ten( -resolved_var->rdigits ); + *rdigits = 0; + } + } + + return retval; + } + +#pragma GCC diagnostic ignored "-Wformat-overflow" + +static time_t +cobol_time() + { + struct timespec tp; + __gg__clock_gettime(CLOCK_REALTIME, &tp); + return tp.tv_sec; + } + +extern "C" +char * +__gg__get_date_yymmdd() + { + char ach[32]; + + time_t t = cobol_time(); + struct tm *local = localtime(&t); + + sprintf(ach, + "%2.2d%2.2d%2.2d", + local->tm_year % 100, + local->tm_mon+1 % 100, + local->tm_mday % 100 ); + + ascii_to_internal_str(ach, strlen(ach)); + return strdup(ach); + } + +extern "C" +char * +__gg__get_date_yyyymmdd() + { + char ach[32]; + + time_t t = cobol_time(); + struct tm *local = localtime(&t); + + sprintf(ach, + "%4.4d%2.2d%2.2d", + local->tm_year + 1900, + local->tm_mon+1, + local->tm_mday); + + ascii_to_internal_str(ach, strlen(ach)); + return strdup(ach); + } + +extern "C" +char * +__gg__get_date_yyddd() + { + char ach[32]; + + time_t t = cobol_time(); + struct tm *local = localtime(&t); + + sprintf(ach, + "%2.2d%3.3d", + local->tm_year % 100, + local->tm_yday+1); + + ascii_to_internal_str(ach, strlen(ach)); + return strdup(ach); + } + +extern "C" +char * +__gg__get_yyyyddd() + { + char ach[32]; + + time_t t = cobol_time(); + struct tm *local = localtime(&t); + + sprintf(ach, + "%4.4d%3.3d", + local->tm_year + 1900, + local->tm_yday+1); + + ascii_to_internal_str(ach, strlen(ach)); + return strdup(ach); + } + +extern "C" +char * +__gg__get_date_dow() + { + char ach[32]; + + time_t t = cobol_time(); + struct tm *local = localtime(&t); + + sprintf(ach, + "%1.1d", + local->tm_wday == 0 ? 7 : local->tm_wday); + + ascii_to_internal_str(ach, strlen(ach)); + return strdup(ach); + } + +static int +int_from_digits(const char * &p, int ndigits) + { + int retval = 0; + while( p && ndigits ) + { + char ch = *p++; + if( isdigit(ch) ) + { + retval *= 10; + retval += (ch & 0xF); + ndigits -= 1; + } + } + return retval; + } + + +extern "C" +void +__gg__clock_gettime(clockid_t clk_id, struct timespec *tp) + { + const char *p = getenv("COB_CURRENT_DATE"); + + if( p ) + { + time_t t; + time (&t); + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + localtime_r(&t, &tm); // This sets tm_isdst for the local time + + tm.tm_year = int_from_digits(p, 4) - 1900; + tm.tm_mon = int_from_digits(p, 2) - 1; + tm.tm_mday = int_from_digits(p, 2); + tm.tm_hour = int_from_digits(p, 2); + tm.tm_min = int_from_digits(p, 2); + tm.tm_sec = int_from_digits(p, 2); + + tm.tm_isdst = 0; + tp->tv_sec = mktime(&tm); + tp->tv_nsec = 0; + if( tm.tm_isdst ) + { + tp->tv_sec -= 3600; + } + } + else + { + clock_gettime(clk_id, tp); + } + } + +extern "C" +char * +__gg__get_date_hhmmssff() + { + char ach[32]; + + struct timespec tv; + __gg__clock_gettime(CLOCK_REALTIME, &tv); + + struct tm tm; + localtime_r(&tv.tv_sec, &tm); + + // // This routine returns local time: + // int day_frac = (tv.tv_sec - timezone) % 86400; + + // int hour = (day_frac / 3600); + // int minute = (day_frac%3600) / 60; + // int second = (day_frac % 60); + int hundredths = tv.tv_nsec/10000000; + + sprintf(ach, + "%2.2d%2.2d%2.2d%2.2d", + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + hundredths); + + ascii_to_internal_str(ach, strlen(ach)); + return strdup(ach); + } + +extern "C" +int +__gg__setop_compare( + const char *candidate, + int capacity, + const char *domain) + { + // This routine is called to compare the characters of 'candidate' + // against the list of character pairs in 'domain' + + int retval = 0; + int ch; + int l; + int h; + const char *d; + + for(int i=0; i= l && ch <= h ) + { + // This character is acceptable + retval = 1; + break; + } + } + + // We checked the entire list of pairs for the candidate character + if( retval == 0 ) + { + // This candidate character failed, so we don't need to check + // the rest of the candidates + break; + } + } + + return retval; + } + +extern "C" +__int128 +__gg__dirty_to_binary_source(const char *dirty, + int length, + int *rdigits) + { + // This routine is used for converting uncontrolled strings to a + // a 128-bit signed binary number. + + // The string can start with a plus or minus + // It can contain a single embedded dot + // The rest of the characters have to be [0-9] + // Any other character, including a second dot, ends processing. + + // So, a "1ABC" will yield 1; "ABC" will yield 0. + + // It takes pointers to "s_hyphen" and "s_rdigits" so that it can + // report what it saw. + + // It returns the binary result. So, 1031.2 returns 10312 and s_rdigits=1 + + // The binary number, if signed, is returned as a negative number. + + __int128 retval = 0; + + int hyphen = 0; + *rdigits = 0; + + // Create a delta_r for counting digits to the right of + // any decimal point. If and when we encounter a decimal separator, + // we'll set this to one, otherwise it'll stay zero. + int delta_r = 0; + + // We now loop over the remaining input characters: + while( length-- >0 ) + { + char ch = *dirty++; + + if( ch == ascii_minus ) + { + hyphen = 1; + continue; + } + if( ch == ascii_plus ) + { + continue; + } + if( ch == __gg__decimal_point && delta_r == 0 ) + { + // This is the first decimal point we've seen, so we + // can start counting rdigits: + delta_r = 1; + continue; + } + if( ch < ascii_0 || ch > ascii_9 ) + { + // When we hit something that isn't a digit, then we are done + break; + } + retval *= 10; + retval += ch - ascii_0; + *rdigits += delta_r; + } + if( !retval ) + { + // Because the result is zero, there can't be a minus sign + hyphen = 0; + } + if( hyphen ) + { + // We saw a minus sign, so negate the result + retval = -retval; + } + return retval; + } + +extern "C" +__int128 +__gg__dirty_to_binary_internal( const char *dirty, + int length, + int *rdigits) + { + // This routine is used for converting uncontrolled strings to a + // a 128-bit signed binary number. + + // The string can start with a plus or minus + // It can contain a single embedded dot + // The rest of the characters have to be [0-9] + // Any other character, including a second dot, ends processing. + + // So, a "1ABC" will yield 1; "ABC" will yield 0. + + // It also can handle 12345E-2 notation. + + // It returns the binary result. So, 1031.2 returns 10312 and rdigits=1 + + // The binary number, if signed, is returned as a negative number. + + // We are limiting the number of digits in the number to MAX_FIXED_POINT_DIGITS + + __int128 retval = 0; + + int digit_count = 0; + int hyphen = 0; + *rdigits = 0; + + // Create a delta_r for counting digits to the right of + // any decimal point. If and when we encounter a decimal separator, + // we'll set this to one, otherwise it'll stay zero. + int delta_r = 0; + + // We now loop over the remaining input characters: + unsigned char ch = '\0'; + + if(length-- > 0) + { + ch = *dirty++; + if( ch == internal_minus ) + { + hyphen = 1; + } + else if( ch == internal_plus ) + { + // A plus sign is okay + } + else if( ch == ascii_to_internal(__gg__decimal_point) ) + { + delta_r = 1; + } + else if( ch >= internal_0 && ch <= internal_9 ) + { + retval = ch - internal_0 ; + if( retval ) + { + digit_count += 1; + } + } + else + { + // Because didn't start with minus, plus, a decimal_place or a digit, + // this isn't a number + length = 0; + ch = '\0'; + } + } + + while( length-- > 0 ) + { + ch = *dirty++; + if( ch == ascii_to_internal(__gg__decimal_point) && delta_r == 0 ) + { + // This is the first decimal point we've seen, so we + // can start counting rdigits: + delta_r = 1; + continue; + } + if( ch < internal_0 || ch > internal_9 ) + { + // When we hit something that isn't a digit, then we are done + break; + } + if( digit_count < MAX_FIXED_POINT_DIGITS ) + { + retval *= 10; + retval += ch - internal_0 ; + *rdigits += delta_r; + if( retval ) + { + digit_count += 1; + } + } + } + + // Let's check for an exponent: + if( ch == internal_E || ch == internal_e ) + { + int exponent = 0; + int exponent_sign = 1; + if( length > 0 ) + { + ch = *dirty; + if( ch == internal_plus) + { + length -= 1; + dirty += 1; + } + else if (ch == internal_minus) + { + exponent_sign = -1; + length -= 1; + dirty += 1; + } + } + while(length-- > 0) + { + ch = *dirty++; + if( ch < internal_0 || ch > internal_9 ) + { + // When we hit something that isn't a digit, then we are done + break; + } + exponent *= 10; + exponent += ch - internal_0 ; + } + exponent *= exponent_sign; + // We need to adjust the retval and the rdigits based on the exponent. + if( exponent < 0) + { + *rdigits += -exponent; + } + else if(exponent > 0) + { + if( exponent <= *rdigits ) + { + *rdigits -= exponent; + } + else + { + // Exponent is > rdigits + retval *= __gg__power_of_ten(exponent - *rdigits); + *rdigits = 0; + } + } + } + + if( !retval ) + { + // Because the result is zero, there can't be a minus sign + hyphen = 0; + } + if( hyphen ) + { + // We saw a minus sign, so negate the result + retval = -retval; + } + return retval; + } + +extern "C" +_Float128 +__gg__dirty_to_float( const char *dirty, + int length) + { + // This routine is used for converting uncontrolled strings to a + // a _Float128 + + // The string can start with a plus or minus + // It can contain a single embedded dot + // The rest of the characters have to be [0-9] + // Any other character, including a second dot, ends processing. + + // So, a "1ABC" will yield 1; "ABC" will yield 0. + + // It also can handle 12345E-2 notation. + + _Float128 retval = 0; + + int rdigits = 0; + int hyphen = 0; + + // Create a delta_r for counting digits to the right of + // any decimal point. If and when we encounter a decimal separator, + // we'll set this to one, otherwise it'll stay zero. + int delta_r = 0; + + // We now loop over the remaining input characters: + char ch = '\0'; + + if(length-- > 0) + { + ch = *dirty++; + if( ch == internal_minus ) + { + hyphen = 1; + } + else if( ch == internal_plus ) + { + // A plus sign is okay + } + else if( ch == ascii_to_internal(__gg__decimal_point) ) + { + delta_r = 1; + } + else if( ch >= internal_0 && ch <= internal_9 ) + { + retval = ch - internal_0 ; + } + else + { + // Because didn't start with minus, plus, a decimal_place or a digit, + // this isn't a number. Set length to zero to prevent additional + // processing + length = 0; + ch = '\0'; + } + } + + while( length-- > 0 ) + { + ch = *dirty++; + if( ch == ascii_to_internal(__gg__decimal_point) && delta_r == 0 ) + { + // This is the first decimal point we've seen, so we + // can start counting rdigits: + delta_r = 1; + continue; + } + if( ch < internal_0 || ch > internal_9 ) + { + // When we hit something that isn't a digit, then we are done + break; + } + retval *= 10; + retval += ch - internal_0 ; + rdigits += delta_r; + } + + // Let's check for an exponent: + int exponent = 0; + if( ch == internal_E || ch == internal_e ) + { + int exponent_sign = 1; + if( length > 0 ) + { + ch = *dirty; + if( ch == internal_plus) + { + length -= 1; + dirty += 1; + } + else if (ch == internal_minus) + { + exponent_sign = -1; + length -= 1; + dirty += 1; + } + } + while(length-- > 0) + { + ch = *dirty++; + if( ch < internal_0 || ch > internal_9 ) + { + // When we hit something that isn't a digit, then we are done + break; + } + exponent *= 10; + exponent += ch - internal_0 ; + } + exponent *= exponent_sign; + } + + // We need to adjust the retval based on rdigits and exponent. + // Notice that 123.45E2 properly comes out to be 12345 + if( exponent - rdigits >= 0 ) + { + retval *= __gg__power_of_ten(exponent - rdigits); + } + else + { + retval /= __gg__power_of_ten(rdigits - exponent); + } + + if( !retval ) + { + // Because the result is zero, there can't be a minus sign + hyphen = 0; + } + if( hyphen ) + { + // We saw a minus sign, so negate the result + retval = -retval; + } + return retval; + } + +extern "C" +__int128 +__gg__get_integer_binary_value(cblc_field_t *var) + { + // This routine is called when a rounded integer is needed + + __int128 retval; + + int rdigits; + + retval = __gg__binary_value_from_field(&rdigits, var); + + while( rdigits-- > 1) + { + retval /= 10; + } + + if( rdigits-- == 1) + { + if( retval < 0 ) + { + retval -= 5; + } + else + { + retval += 5; + } + retval /= 10; + } + + return retval; + } + +static +void psz_to_internal(char *psz) + { + char *p = psz; + while( *p ) + { + *p = ascii_to_internal(*p); + p += 1; + } + } + +static int +get_scaled_rdigits(cblc_field_t *field) + { + int retval; + if( !(field->attr & scaled_e) ) + { + // The value is not P-scaled, so we just use the unchanged rdigits value + retval = field->rdigits; + } + else + { + if( field->rdigits < 0 ) + { + // The PIC string was something like 999PPPP, which means an rdigits value + // of -4. We return zero; somebody else will have the job of multiplying + // the three significant digits by 10^4 to get the magnitude correct. + retval = 0; + } + else + { + // The PIC string was something like PPPP999, which means an rdigits value + // of +4. We return an rdigits value of 4 + 3 = 7, which will mean that + // the three significant digits will be scaled to 0.0000999 + retval = field->digits + field->rdigits; + } + } + return retval; + } + +static char * +format_for_display_internal(char **dest, + size_t *dest_size, + cblc_field_t *var, + unsigned char *actual_location, + int actual_length, + int address_of) + { + // dest and dest_size represent a malloced buffer of dest_size. + + // This routine will put the formatted result into dest if it fits, and + // realloc dest if it doesn't. The new_size goes into the dest_size + // reference. Used properly, the caller's buffer just keeps getting bigger + // as necessary, cutting down on the number of reallocations needed. + + int source_rdigits = var->rdigits; + + if( var->attr & scaled_e ) + { + source_rdigits = 0; + } + + // Special case, when var->address_of is on + + if( address_of ) + { + // Assume that DISPLAY OF ADDRESS OF should be what's expected: + + __gg__realloc_if_necessary(dest, dest_size, 2*sizeof(void *) + 1); + + sprintf( *dest, + "0x%*.*lx", + (int)(2*sizeof(void *)), + (int)(2*sizeof(void *)), + (unsigned long)actual_location); + ascii_to_internal_str(*dest, strlen(*dest)); + + goto done; + } + + switch( var->type ) + { + case FldLiteralA: + case FldGroup: + case FldAlphanumeric: + case FldNumericEdited: + case FldAlphaEdited: + __gg__realloc_if_necessary(dest, dest_size, actual_length+1); + if( actual_location ) + { + memcpy(*dest, actual_location, actual_length); + } + else + { + fprintf(stderr, "attempting to display a NULL pointer in %s\n", var->name); + abort(); + //memset(*dest, internal_query, actual_length); + //memcpy(*dest, actual_location, actual_length); + } + (*dest)[actual_length] = NULLCH; + break; + + case FldNumericDisplay: + { + // We are going to make use of fact that a NumericDisplay's data is + // almost already in the format we need. We have to add a decimal point, + // if necessary, in the right place, and we need to tack on leading or + // trailing zeroes for PPP999 and 999PPP scaled-e variables. + + if( var_is_refmod(var) ) + { + __gg__realloc_if_necessary(dest, dest_size, actual_length+1); + memcpy((*dest), actual_location, actual_length); + (*dest)[actual_length] = NULLCH; + break; + } + + unsigned char *running_location = actual_location; + + // We need the counts of digits to the left and right of the decimal point + int rdigits = get_scaled_rdigits(var); + int ldigits = var->digits - rdigits; + + // Calculate the minimum allocated size we need, keeping in mind that + // ldigits can be negative when working with a PPP999 number + int nsize = std::max(ldigits,0) + rdigits+1; + if( ldigits < 0 ) + { + // We are dealing with a scaled_e number + rdigits += ldigits; + } + + int index = 0; // This is the running index into our output destination + if( rdigits ) + { + // We need room for the inside decimal point + nsize += 1; + } + if( var->attr & signable_e ) + { + // We need room for a leading or trailing sign in the output + nsize += 1; + } + + // nsize is now the actual number of bytes we need in the destination + __gg__realloc_if_necessary(dest, dest_size, nsize); + + if( actual_location ) + { + if( var->attr & signable_e ) + { + if( var->attr & separate_e ) + { + // We are dealing with a sign character maintained separately in + // the data. + if( var->attr & leading_e ) + { + // The first character is the sign character + (*dest)[index++] = *running_location++; + } + } + else + { + // The sign character is not separate. It's in either the first + // or last byte of the data: + size_t sign_location = var->attr & leading_e ? 0 : actual_length-1 ; + if( is_sign_bit_on( actual_location[sign_location]) ) + { + (*dest)[index++] = internal_minus; + } + else + { + (*dest)[index++] = internal_plus; + } + } + } + + {//xxx + // copy over the characters to the left of the decimal point: + for(int i=0; irdigits < 0 ) + { + for(int i=0; i < -(var->rdigits); i++) + { + (*dest)[index++] = internal_zero; + } + } + + if( var->attr & signable_e + && var->attr & separate_e + && !(var->attr & leading_e) ) + { + (*dest)[index++] = actual_location[actual_length-1]; + } + + (*dest)[index++] = NULLCH; + } + else + { + fprintf(stderr, "attempting to display a NULL pointer in %s\n", var->name); + abort(); + // memset(*dest, internal_query, nsize-1); + // (*dest)[nsize] = NULLCH; + } + } + break; + + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + { + int dummy; + int digits; + __int128 value = get_binary_value_local(&dummy, + var, + actual_location, + actual_length); + // Perhaps weirdly, for a p-scaled value with negative rdigits, + // value has been scaled by 10**(-rdigits), because for most purposes, + // get_binary_value_local should be the actual value. But for display, + // we need to bring it back down by that factor, because down below we + // will be adding zeroes to the right. This is a tug-of-war between + // USAGE DISPLAY and other USAGES: + + if( (var->attr & scaled_e) && var->rdigits < 0 ) + { + value = __gg__scale_by_power_of_ten_2(value, var->rdigits); + } + + if( var->digits ) + { + digits = var->digits; + } + else + { + // USAGE BINARY comes through without a digits value. Force it based on + // the capacity: + switch( var->capacity ) + { + case 1: + digits = 3; + break; + case 2: + digits = 5; + break; + case 4: + digits = 10; + break; + case 8: + digits = 19; + break; + case 16: + digits = 38; + break; + default: + warnx("%s(): %s has capacity %ld\n", + __func__, + var->name, + var->capacity); + abort(); + break; + } + } + + char ach[128]; + __gg__binary_to_string_internal(ach, digits, value); + + // And copy the code from up above: + int nsize = digits+1; + int index = 0; + if( source_rdigits ) + { + // We need room for the inside decimal point + nsize += 1; + } + if( var->attr & signable_e ) + { + // We need room for the leading sign + nsize += 1; + } + __gg__realloc_if_necessary(dest, dest_size, nsize); + + bool is_signed = value < 0; + + if( var->attr & signable_e ) + { + if( is_signed ) + { + (*dest)[index++] = internal_minus; + } + else + { + (*dest)[index++] = internal_plus; + } + } + // copy over the characters to the left of the decimal point: + memcpy((*dest)+index, ach, digits - source_rdigits); + index += digits - source_rdigits; + if( source_rdigits ) + { + (*dest)[index++] = ascii_to_internal(__gg__decimal_point); + memcpy((*dest)+index, ach+(digits-source_rdigits), source_rdigits); + index += source_rdigits; + } + (*dest)[index++] = NULLCH ; + } + break; + + case FldIndex: + { + // The display of a FldIndex doesn't need to provide clues about its + // length, so don't bother with leading zeroes. + int dummy; + __int128 value = get_binary_value_local(&dummy, + var, + actual_location, + actual_length); + char ach[64]; + sprintf(ach, "%lu", (size_t)value); + __gg__realloc_if_necessary(dest, dest_size, strlen(ach)+1); + strcpy(*dest, ach); + } + break; + + case FldClass: + { + if( var->level != LEVEL88 ) + { + size_t retsize = MINIMUM_ALLOCATION_SIZE; + memset(*dest, 0, retsize); + strcpy(*dest, ""); + } + else + { + // This is a LEVEL 88 variable + size_t retsize = MINIMUM_ALLOCATION_SIZE; + memset(*dest, 0, retsize); + strcpy(*dest, ""); + } + + break; + } + + case FldPointer: + { + int digits; + __int128 value = get_binary_value_local( &digits, + var, + actual_location, + actual_length); + __gg__realloc_if_necessary(dest, dest_size, 2*sizeof(void *) + 3); + + sprintf( *dest, + "0x%*.*lx", + (int)(2*sizeof(void *)), + (int)(2*sizeof(void *)), + (unsigned long)value); + ascii_to_internal_str(*dest, strlen(*dest)); + break; + } + + case FldFloat: + { + switch(var->capacity) + { + case 4: + { + // We will convert based on the fact that for float32, any seven-digit + // number converts to float32 and then back again unchanged. + + // We will also format numbers so that we produce 0.01 and 1E-3 on the low + // side, and 9999999 and then 1E+7 on the high side + // 10,000,000 = 1E7 + char ach[64]; + _Float32 floatval = *(_Float32 *)actual_location; + strfromf32(ach, sizeof(ach), "%.9E", floatval); + char *p = strchr(ach, 'E'); + if( !p ) + { + // Probably INF -INF NAN or -NAN, so ach has our result + } + else + { + p += 1; + int exp = atoi(p); + if( exp >= 6 || exp <= -5 ) + { + // We are going to stick with the E notation, so ach has our result + } + else + { + // We are going to produce our number in such a way that we specify + // seven signicant digits, no matter where the decimal point lands. + // Note that exp is in the range of 6 to -2 + + int precision = 9 - exp; + sprintf(ach, "%.*f", precision, (double)floatval ); + } + __gg__remove_trailing_zeroes(ach); + __gg__realloc_if_necessary(dest, dest_size, strlen(ach)+1); + } + psz_to_internal(ach); + strcpy(*dest, ach); + break; + } + + case 8: + { + // We will convert based on the fact that for float32, any 15-digit + // number converts to float64 and then back again unchanged. + + // We will also format numbers so that we produce 0.01 and 1E-3 on the low + // side, and 9999999 and then 1E+15 on the high side + char ach[64]; + _Float64 floatval = *(_Float64 *)actual_location; + strfromf64(ach, sizeof(ach), "%.17E", floatval); + char *p = strchr(ach, 'E'); + if( !p ) + { + // Probably INF -INF NAN or -NAN, so ach has our result + } + else + { + p += 1; + int exp = atoi(p); + if( exp >= 6 || exp <= -5 ) + { + // We are going to stick with the E notation, so ach has our result + } + else + { + // We are going to produce our number in such a way that we specify + // seven signicant digits, no matter where the decimal point lands. + // Note that exp is in the range of 6 to -2 + + int precision = 17 - exp; + + sprintf(ach, "%.*f", precision, (double)floatval ); + } + __gg__remove_trailing_zeroes(ach); + __gg__realloc_if_necessary(dest, dest_size, strlen(ach)+1); + } + psz_to_internal(ach); + strcpy(*dest, ach); + break; + } + + case 16: + { + // We will convert based on the fact that for float32, any 15-digit + // number converts to float64 and then back again unchanged. + + // We will also format numbers so that we produce 0.01 and 1E-3 on the low + // side, and 9999999 and then 1E+15 on the high side + char ach[128]; + // We can't use *(_Float64 *)actual_location; + // That uses the SSE registers, which won't work if the source isn't + // on a 16-bit boundary. + _Float128 floatval; + memcpy(&floatval, actual_location, 16); + strfromf128(ach, sizeof(ach), "%.36E", floatval); + char *p = strchr(ach, 'E'); + if( !p ) + { + // Probably INF -INF NAN or -NAN, so ach has our result + } + else + { + p += 1; + int exp = atoi(p); + if( exp >= 6 || exp <= -5 ) + { + // We are going to stick with the E notation, so ach has our result + } + else + { + // We are going to produce our number in such a way that we specify + // seven signicant digits, no matter where the decimal point lands. + // Note that exp is in the range of 6 to -2 + + int precision = 36 - exp; + char achFormat[24]; + sprintf(achFormat, "%%.%df", precision); + strfromf128(ach, sizeof(ach), achFormat, floatval); + } + __gg__remove_trailing_zeroes(ach); + __gg__realloc_if_necessary(dest, dest_size, strlen(ach)+1); + } + + psz_to_internal(ach); + strcpy(*dest, ach); + break; + } + } + break; + } + + default: + fprintf(stderr, + "Unknown conversion %d in format_for_display_internal\n", + var->type ); + abort(); + break; + } + + if( var->attr & scaled_e && var->type != FldNumericDisplay ) + { + static size_t buffer_size = MINIMUM_ALLOCATION_SIZE; + static char * buffer = (char *)malloc(buffer_size); + if( var->rdigits > 0) + { + // We have something like 123 or +123. We need to insert a decimal + // point and a rdigits zeroes to make it +.000000123 + + size_t new_length = strlen(*dest) + var->rdigits + 1 + 1; + __gg__realloc_if_necessary(&buffer, &buffer_size, new_length); + + + memset(buffer, internal_0, new_length); + char *p = buffer; + char *s = *dest; + if( ((*dest)[0]&0xFF) < internal_0 + || ((*dest)[0]&0xFF) > internal_9 ) + { + *p++ = (*dest)[0]; + s += 1; + } + *p++ = ascii_to_internal(__gg__decimal_point); + p += var->rdigits; // Skip over the zeroes + strcpy(p, s); + + __gg__realloc_if_necessary(dest, dest_size, new_length); + strcpy(*dest, buffer); + } + else // var->rdigits < 0 + { + // We have something like 123 or +123. All we need to do is + // add zeroes to the end: + size_t new_length = strlen(*dest) + -var->rdigits + 1; + __gg__realloc_if_necessary(&buffer, &buffer_size, new_length); + + memset(buffer, internal_0, new_length); + buffer[new_length-1] = NULLCH; + memcpy(buffer, *dest, strlen(*dest)); + + __gg__realloc_if_necessary(dest, dest_size, new_length); + strcpy(*dest, buffer); + } + } + + if( var->type == FldNumericBin5 && (var->attr & intermediate_e) ) + { + // Because this is a intermediate Bin5, let's strip off leading zeroes. + // + // Because we don't know what we are dealing with, we created a 38-digit + // number with a variable number of rdigits. So, we usually have a boatload + // of leading zeroes. I find that display offensive, so let's fix it: + unsigned char *p1 = (unsigned char *)(*dest); + if( *p1 == internal_plus || *p1 == internal_minus ) + { + p1 += 1; + } + unsigned char *p2 = p1; + while( p2[0] == internal_zero && p2[1] != '\0' ) + { + p2 += 1; + } + strcpy((char *)p1, (char *)p2); + } + + done: + return *dest; + } + +static char * +format_for_display_local( char **dest, + size_t *dest_size, + cblc_field_t *var, + size_t var_offset, + size_t var_size, + int var_flags) + { + if(var) + { + // At this point, format the entire length. It's up to our caller to + // trim it further, because this routine is used by both receivers and + // senders + format_for_display_internal(dest, + dest_size, + var, + var->data + var_offset, + var_size, + var_flags & REFER_T_ADDRESS_OF); + } + else + { + **dest = '\0'; + } + return *dest; + } + +static int +compare_88( const char *list, + const char *list_e, + bool fig_const, + cblc_field_t * /*conditional*/, + unsigned char *conditional_location, + int conditional_length) + { + int list_len = (int)(list_e-list); + int test_len; + char *test; + if( fig_const ) + { + // We are working with a figurative constant + + test = (char *)malloc(conditional_length); + test_len = conditional_length; + // This is where we handle the zero-length strings that + // nonetheless can magically be expanded into figurative + // constants: + + int ch = internal_space; + // Check for the strings starting with 0xFF whose second character + // indicates a figurative constant: + if( list[0] == ascii_Z ) + { + ch = internal_zero; + } + else if( list[0] == ascii_H ) + { + if( __gg__high_value_character == DEGENERATE_HIGH_VALUE ) + { + ch = __gg__high_value_character; + } + else + { + ch = ascii_to_internal(__gg__high_value_character); + } + } + else if( list[0] == ascii_Q ) + { + ch = ascii_to_internal(__gg__quote_character); + } + else if( list[0] == ascii_L ) + { + ch = ascii_to_internal(__gg__low_value_character); + } + memset( test, ch, conditional_length ); + } + else if( list_len < conditional_length ) + { + // 'list' is too short; we have to right-fill with spaces: + test = (char *)malloc(conditional_length); + test_len = conditional_length; + memset(test, internal_space, conditional_length); + memcpy(test, list, list_len); + } + else + { + test = (char *)malloc(list_len); + test_len = list_len; + memcpy(test, list, list_len); + } + + int cmpval; + + if( test[0] == NULLCH && conditional_location[0] == 0) + { + cmpval = 0; + } + else + { + cmpval = cstrncmp(test, (char *)conditional_location, conditional_length); + if( cmpval == 0 && (int)strlen(test) != conditional_length ) + { + // When strncmp returns 0, the actual smaller string is the + // the shorter of the two: + cmpval = test_len - conditional_length; + } + } + + free(test); + + if( cmpval < 0 ) + { + cmpval = -1; + } + else if(cmpval > 0) + { + cmpval = +1; + } + return cmpval; + } + +static _Float128 +get_float128( cblc_field_t *field, + unsigned char *location ) + { + _Float128 retval=0; + if(field->type == FldFloat ) + { + switch( field->capacity ) + { + case 4: + retval = *(_Float32 *)location; + break; + case 8: + retval = *(_Float64 *)location; + break; + case 16: + // retval = *(_Float128 *)location; doesn't work, because the SSE + // registers need the source on a 16-byte boundary, and we can't + // guarantee that. + memcpy(&retval, location, 16); + break; + } + } + else if( field->type == FldLiteralN ) + { + if( __gg__decimal_point == '.' ) + { + retval = strtof128(field->initial, NULL); + } + else + { + // We need to replace any commas with periods + static size_t size = 128; + static char *buffer = (char *)malloc(size); + while( strlen(field->initial)+1 > size ) + { + size *= 2; + buffer = (char *)malloc(size); + } + strcpy(buffer, field->initial); + char *p = strchr(buffer, ','); + if(p) + { + *p = '.'; + } + retval = strtof128(buffer, NULL); + } + } + else + { + fprintf(stderr, "What's all this then?\n"); + abort(); + } + return retval; + } + +static +int +compare_field_class(cblc_field_t *conditional, + unsigned char *conditional_location, + int conditional_length, + cblc_field_t *list) + { + int retval = 1; // Zero means equal + __int128 value; + int rdigits; + + // list->initial points to a superstring: a double-null terminated + // string containing pairs of strings. We are looking for equality. + + switch( conditional->type ) + { + case FldNumericDisplay: + case FldNumericEdited: + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldIndex: + { + value = get_binary_value_local (&rdigits, + conditional, + conditional_location, + conditional_length); + char *walker = list->initial; + while(*walker) + { + char left_flag; + size_t left_len; + char * left; + + char right_flag; + size_t right_len; + char * right; + + char *pend; + left_len = strtoull(walker, &pend, 10); + left_flag = *pend; + left = pend+1; + + right = left + left_len; + right_len = strtoull(right, &pend, 10); + right_flag = *pend; + right = pend+1; + + walker = right + right_len; + + int left_rdigits; + int right_rdigits; + + __int128 left_value; + if( left_flag == 'F' && left[0] == 'Z' ) + { + left_value = 0; + left_rdigits = 0; + } + else + { + left_value = __gg__dirty_to_binary_internal( + left, + left_len, + &left_rdigits); + } + + __int128 right_value; + if( right_flag == 'F' && right[0] == 'Z' ) + { + right_value = 0; + right_rdigits = 0; + } + else + { + right_value = __gg__dirty_to_binary_internal( + right, + right_len, + &right_rdigits); + } + + // Normalize all three numbers to the same rdigits + int max = std::max(rdigits, left_rdigits); + max = std::max(max, right_rdigits); + + if( max > rdigits ) + { + value *= __gg__power_of_ten(max - rdigits); + } + if( max > left_rdigits ) + { + left_value *= __gg__power_of_ten(max - left_rdigits); + } + if( max > right_rdigits ) + { + right_value *= __gg__power_of_ten(max - right_rdigits); + } + if( left_value <= value && value <= right_value ) + { + retval = 0; + break; + } + } + break; + } + + case FldGroup: + case FldAlphanumeric: + case FldLiteralA: + { + char *walker = list->initial; + while(*walker) + { + bool fig1; + bool fig2; + char *first; + char *last; + char *first_e; + char *last_e; + size_t first_len; + size_t last_len; + + char *pend; + + first = walker; + first_len = strtoull(first, &pend, 10); + fig1 = *pend == 'F'; + first = pend+1; + first_e = first + first_len; + + last = first_e; + + last_len = strtoull(last, &pend, 10); + fig2 = *pend == 'F'; + last = pend+1; + last_e = last + last_len; + + walker = last_e; + + int compare_result; + + compare_result = compare_88(first, + first_e, + fig1, + conditional, + conditional_location, + conditional_length); + if( compare_result > 0 ) + { + // First is > conditional, so this is no good + continue; + } + compare_result = compare_88(last, + last_e, + fig2, + conditional, + conditional_location, + conditional_length); + if( compare_result < 0 ) + { + // Last is < conditional, so this is no good + continue; + } + + // conditional is inclusively between first and last + retval = 0; + break; + } + break; + } + + case FldFloat: + { + _Float128 value = get_float128(conditional, conditional_location) ; + char *walker = list->initial; + while(*walker) + { + char left_flag; + size_t left_len; + char * left; + + char right_flag; + size_t right_len; + char * right; + + char *pend; + left_len = strtoull(walker, &pend, 10); + left_flag = *pend; + left = pend+1; + + right = left + left_len; + right_len = strtoull(right, &pend, 10); + right_flag = *pend; + right = pend+1; + + walker = right + right_len; + + _Float128 left_value; + if( left_flag == 'F' && left[0] == 'Z' ) + { + left_value = 0; + } + else + { + left_value = __gg__dirty_to_float(left, + left_len); + } + + _Float128 right_value; + if( right_flag == 'F' && right[0] == 'Z' ) + { + right_value = 0; + } + else + { + right_value = __gg__dirty_to_float( right, + right_len); + } + + if( left_value <= value && value <= right_value ) + { + retval = 0; + break; + } + } + break; + } + + default: + printf( "%s(): doesn't know what to do with %s\n", + __func__, + conditional->name); + abort(); + } + + return retval; + } + +static +bool +local_is_numeric(int type, bool address_of) + { + bool retval; + if( address_of ) + { + retval = true; + } + else + { + switch(type) + { + case FldNumericDisplay: + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldIndex: + case FldPointer: + case FldLiteralN: + case FldFloat: + retval = true; + break; + default: + retval = false; + break; + } + } + return retval; + } + +static +bool +local_is_alpha(int type, bool address_of) + { + bool retval; + if( address_of ) + { + retval = false; + } + else + { + switch(type) + { + case FldGroup: + case FldAlphanumeric: + case FldAlphaEdited: + case FldNumericEdited: + case FldLiteralA: + retval = true; + break; + default: + retval = false; + break; + } + } + return retval; + } + +static +int +compare_strings(char *left_string, + size_t left_length, + bool left_all, + char *right_string, + size_t right_length, + bool right_all) + { + int retval = 0; + size_t i = 0; + + if( right_all && right_length > left_length ) + { + // In the rubber-bandy ALL situation, and the ALL is longer than the + // fixed side, we just compare the characters of the fixed side: + right_length = left_length; + } + + if( left_all && left_length > right_length ) + { + left_length = right_length; + } + + while( !retval && i right_length ) + { + left_length = right_length; + } + while( !retval && itype == FldClass ) + { + return compare_field_class( left_side, + left_location, + left_length, + right_side); + } + + // Serene in our conviction that the left_side isn't a FldClass, we + // move on: + + cbl_figconst_t left_figconst = (cbl_figconst_t)(left_attr & FIGCONST_MASK); + cbl_figconst_t right_figconst = (cbl_figconst_t)(right_attr & FIGCONST_MASK); + + unsigned int fig_left = 0; + unsigned int fig_right = 0; + + switch(left_figconst) + { + case normal_value_e : + fig_left = 0; + break; + case low_value_e : + fig_left = ascii_to_internal(__gg__low_value_character); + break; + case zero_value_e : + fig_left = internal_zero; + break; + case space_value_e : + fig_left = internal_space; + break; + case quote_value_e : + fig_left = ascii_to_internal(__gg__quote_character); + break; + case high_value_e : + if( __gg__high_value_character == DEGENERATE_HIGH_VALUE ) + { + fig_left = __gg__high_value_character; + } + else + { + fig_left = ascii_to_internal(__gg__high_value_character); + } + break; + case null_value_e: + break; + } + switch(right_figconst) + { + case normal_value_e : + fig_right = 0; + break; + case low_value_e : + fig_right = ascii_to_internal(__gg__low_value_character); + break; + case zero_value_e : + fig_right = internal_zero; + break; + case space_value_e : + fig_right = internal_space; + break; + case quote_value_e : + fig_right = ascii_to_internal(__gg__quote_character); + break; + case high_value_e : + if( __gg__high_value_character == DEGENERATE_HIGH_VALUE ) + { + fig_right = __gg__high_value_character; + } + else + { + fig_right = ascii_to_internal(__gg__high_value_character); + } + break; + case null_value_e: + break; + } + + // We have four high-level conditions to consider: + int retval = 0; + bool compare = false; + + if( left_figconst && right_figconst ) + { + // We are comparing two figurative constants + retval = collated(fig_left) - collated(fig_right); + compare = true; + goto fixup_retval; + } + if( left_figconst && !right_figconst ) + { + // Go directly to fixup_retval. Because 'compare' is false, we'll + // end up trying again with the variables swapped: + goto fixup_retval; + } + if( !left_figconst && right_figconst ) + { + // We are comparing the left side to a figurative constant: + switch( right_figconst ) + { + default: + fprintf(stderr, + "%s() %s:%d -- Unknown figurative constant %d\n", + __func__, __FILE__, __LINE__, + (int)right_figconst); + abort(); + break; + + case null_value_e: + break; + + case low_value_e: + case high_value_e: + case quote_value_e: + case space_value_e: + retval = 0; + for(size_t i=0; itype ) + { + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldNumericDisplay: + case FldLiteralN: + case FldIndex: + case FldPointer: + // ZEROES is a chameleon. When compared to a numeric, it is + // the number zero: + { + int rdigits; + __int128 value; + + if( left_side) + + value = get_binary_value_local( &rdigits, + left_side, + left_location, + left_length); + retval = 0; + retval = value < 0 ? -1 : retval; + retval = value > 0 ? 1 : retval; + break; + } + + case FldFloat: + { + _Float128 value = __gg__float128_from_location(left_side, + left_location); + retval = 0; + retval = value < 0 ? -1 : retval; + retval = value > 0 ? 1 : retval; + break; + } + + default: + // We are comparing a alphanumeric string to ZEROES + retval = 0; + for(size_t i=0; itype, left_address_of) + && local_is_alpha(right_side->type, right_address_of) ) + { + retval = compare_strings( (char *)left_location, + left_length, + left_all, + (char *)right_location, + right_length, + right_all ); + + compare = true; + goto fixup_retval; + } + + if( local_is_numeric(left_side->type, left_address_of) + && local_is_numeric(right_side->type, right_address_of) ) + { + if( left_side->type == FldFloat && right_side->type == FldFloat ) + { + // One or the other of the numerics is a FldFloat + _Float128 left_value = __gg__float128_from_location(left_side, left_location); + _Float128 right_value = __gg__float128_from_location(right_side, right_location); + retval = 0; + retval = left_value < right_value ? -1 : retval; + retval = left_value > right_value ? 1 : retval; + compare = true; + goto fixup_retval; + } + + if( left_side->type == FldFloat ) + { + // The left side is a FldFloat; the other is another type of numeric: + int rdecimals; + _Float128 left_value; + _Float128 right_value; + + if( right_side->type == FldLiteralN) + { + // In order to do the comparision, we need the value from the + // literal to be the same flavor as the left side: + // We need to replace any commas with periods + static size_t size = 128; + static char *buffer = (char *)malloc(size); + while( strlen(right_side->initial)+1 > size ) + { + size *= 2; + buffer = (char *)malloc(size); + } + strcpy(buffer, right_side->initial); + if( __gg__decimal_point == ',' ) + { + // We need to replace any commas with periods + char *p = strchr(buffer, ','); + if(p) + { + *p = '.'; + } + } + + // buffer[] now contains the string we want to convert + + switch(left_side->capacity) + { + case 4: + { + _Float32 left_value = *(_Float32 *)left_location; + _Float32 right_value = strtof32(buffer, NULL); + retval = 0; + retval = left_value < right_value ? -1 : retval; + retval = left_value > right_value ? 1 : retval; + break; + } + case 8: + { + _Float64 left_value = *(_Float64 *)left_location; + _Float64 right_value = strtof64(buffer, NULL); + retval = 0; + retval = left_value < right_value ? -1 : retval; + retval = left_value > right_value ? 1 : retval; + break; + } + case 16: + { + //_Float128 left_value = *(_Float128 *)left_location; + _Float128 left_value; + memcpy(&left_value, left_location, 16); + _Float128 right_value = strtof128(buffer, NULL); + retval = 0; + retval = left_value < right_value ? -1 : retval; + retval = left_value > right_value ? 1 : retval; + break; + } + } + } + else + { + left_value = __gg__float128_from_location(left_side, left_location); + + right_value = get_binary_value_local( &rdecimals, + right_side, + right_location, + right_length); + right_value /= __gg__power_of_ten(rdecimals); + retval = 0; + retval = left_value < right_value ? -1 : retval; + retval = left_value > right_value ? 1 : retval; + } + + compare = true; + goto fixup_retval; + } + + if( left_side->type != FldFloat && right_side->type != FldFloat) + { + // We are comparing a numeric to a numeric, neither are floats + int ldecimals; + int rdecimals; + __int128 left_value; + __int128 right_value; + + if( left_address_of ) + { + left_value = (__int128)left_location; + ldecimals = 0; + } + else + { + left_value = get_binary_value_local( &ldecimals, + left_side, + left_location, + left_length); + } + if( right_address_of ) + { + right_value = (__int128)right_location; + rdecimals = 0; + } + else + { + right_value = get_binary_value_local( &rdecimals, + right_side, + right_location, + right_length); + } + + // We need to align the decimal points: + if(rdecimals > ldecimals) + { + left_value *= __gg__power_of_ten(rdecimals-ldecimals); + } + else if( ldecimals > rdecimals ) + { + right_value *= __gg__power_of_ten(ldecimals-rdecimals); + } + + retval = 0; + retval = left_value < right_value ? -1 : retval; + retval = left_value > right_value ? 1 : retval; + compare = true; + goto fixup_retval; + } + } + + if( local_is_alpha(left_side->type, left_address_of) + && local_is_numeric(right_side->type, right_address_of) ) + { + // We are comparing an alphanumeric to a numeric. + + // The trick here is to convert the numeric to its display form, + // and compare that to the alphanumeric. For example, when comparing + // a VAL5 PIC X(3) VALUE 5 to literals, + // + // VAL5 EQUAL 5 is TRUE + // VAL5 EQUAL 005 is TRUE + // VAL5 EQUAL "5" is FALSE + // VAL5 EQUAL "005" is TRUE + + if( left_side->type == FldLiteralA ) + { + left_location = (unsigned char *)left_side->data; + left_length = left_side->capacity; + } + + static size_t right_string_size = MINIMUM_ALLOCATION_SIZE; + static char *right_string = (char *)malloc(right_string_size); + + right_string = format_for_display_internal( + &right_string, + &right_string_size, + right_side, + right_location, + right_length, + 0); + + // There is a tricky aspect to comparing an alphanumeric to + // a string. In short, we have to strip off any leading plus sign + + // And, according to the NIST tests, the same is true for minus signs. + // Apparently, when comparing a number to an alphanumeric, it is + // considered a "pseudo-move", and the rule for moving a negative + // number to an alphanumeric is that negative signs get stripped off + + if( *left_location == internal_plus || *left_location == internal_minus ) + { + left_location += 1; + left_length -= 1; + } + + char *right_fixed; + if( *right_string == internal_plus || *right_string == internal_minus ) + { + right_fixed = right_string + 1; + } + else + { + right_fixed = right_string; + } + + retval = compare_strings( (char *)left_location, + left_length, + left_all, + right_fixed, + strlen(right_fixed), + right_all); + compare = true; + goto fixup_retval; + } + } + +fixup_retval: + + if( !compare && !second_time_through) + { + // This is the first time through, and we couldn't do the comparison. + // Maybe we have to reverse the inputs: + retval = __gg__compare_2( right_side, + right_location, + right_length, + right_attr, + right_all, + right_address_of, + left_side, + left_location, + left_length, + left_attr, + left_all, + left_address_of, + 1); + // And reverse the sense of the return value: + compare = true; + retval = -retval; + } + + if( !compare && second_time_through ) + { + // Nope. We still couldn't do the comparison + fprintf(stderr, "###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); + fprintf(stderr, "###### We don't know how to compare types %d and %d\n", + left_side->type, + right_side->type); + __gg__abort("__gg__compare_2() couldn't do the comparison"); + } + + // Normalize negative and positive to just -1 and +1 + if( retval < 0 ) + { + retval = -1; + } + else if( retval > 0) + { + retval = 1; + } + return retval; + } + +extern "C" +int +__gg__compare(struct cblc_field_t *left, + size_t left_offset, + size_t left_length, + size_t left_flags, + struct cblc_field_t *right, + size_t right_offset, + size_t right_length, + size_t right_flags, + int second_time_through ) + { + int retval; + left_length = left_length ? left_length : left->capacity; + right_length = right_length ? right_length : right->capacity; + retval = __gg__compare_2( left, + left->data + left_offset, + left_length, + left->attr, + !!(left_flags & REFER_T_MOVE_ALL), + !!(left_flags & REFER_T_ADDRESS_OF), + right, + right->data + right_offset, + right_length, + right->attr, + !!(right_flags & REFER_T_MOVE_ALL), + !!(right_flags & REFER_T_ADDRESS_OF), + second_time_through); + return retval; + } + +extern "C" +void +__gg__double_to_target(cblc_field_t *tgt, double tgt_value, cbl_round_t rounded) + { + int tgt_rdigits = 0; + + if( tgt->attr & intermediate_e ) + { + // We are calculating an intermediate result. We want to keep as + // much of the fractional part as we can. We are using a double, + // which can hold almost 16 digits. So, keep multiplying non-zero + // value by 10 until it's that big. Limit the number of + // multiplies, in case we were given a ridiculously tiny number to + // begin with: + const double digits = 1E15; + + if( tgt_value ) + { + while( tgt_value > -digits && tgt_value < digits && tgt_rdigits < 15 ) + { + tgt_value *= 10.0; + tgt_rdigits += 1; + } + } + // Alter the run-time target's rdigits + tgt->rdigits = tgt_rdigits; + } + else + { + // We want a specific number of rdigits. We will multiply by + // 10^(tgt->rdigits + 1), to allow for the possibility of rounding: + tgt_rdigits = tgt->rdigits+1; + for(int i=0; i &offsets, + size_t key_base, + size_t nkeys, + cblc_field_t **keys, + size_t *ascending, + int /*duplicates*/) + { + sorter.contents = contents; + sorter.offsets = offsets.data(); + sorter.base = key_base, + sorter.nkeys = nkeys; + sorter.keys = keys; + sorter.ascending = ascending; + + std::sort(offsets.begin(), offsets.end(), compare_for_sort_table); + } + +extern "C" +void +__gg__sort_table( cblc_field_t *table, + size_t table_o, + size_t depending_on, + size_t nkeys, + cblc_field_t **keys, + size_t *ascending, + int duplicates ) + { + size_t buffer_size = 128; + unsigned char *contents = (unsigned char *)malloc(buffer_size); + size_t offset = 0; + std::vectoroffsets; + size_t record_size = table->capacity; + unsigned char *next_record = table->data + table_o; + + // Convert the table to our normalized form + for(size_t i=0; i buffer_size ) + { + buffer_size *= 2; + contents = (unsigned char *)realloc(contents, buffer_size); + } + offsets.push_back(offset); + memcpy(contents+offset, &record_size, sizeof(size_t)); + offset += sizeof(size_t); + memcpy(contents+offset, next_record, record_size); + offset += record_size; + next_record += record_size; + } + + // Sort it + sort_contents(contents, + offsets, + table->offset, + nkeys, + keys, + ascending, + duplicates); + + // Put the sorted contents back + next_record = table->data + table_o; + for(size_t i=0; iname, flag_bits); + + if( flag_bits & JUST_ONCE_BIT && var->attr & initialized_e ) + { + return; + } + + bool is_redefined = !!(flag_bits & REDEFINED_BIT); + bool explicitly = !!(flag_bits & EXPLICIT_BIT); + bool defaultbyte_in_play = !!(flag_bits & DEFAULTBYTE_BIT); + char defaultbyte = flag_bits & DEFAULT_BYTE_MASK; + unsigned int nsubscripts = (flag_bits & NSUBSCRIPT_MASK) >> NSUBSCRIPT_SHIFT; + + if( var->data == NULL + && var->attr & (intermediate_e) + && var->type != FldLiteralA + && var->type != FldLiteralN ) + { + //fprintf(stderr, "ABORTING on %2.2d %s %d\n", var->level, var->name, var->type); + //abort(); + var->data = (unsigned char *)malloc(var->capacity); + } + + // Set the "initialized" bit, which is tested in parser_symbol_add to make + // sure this code gets executed only once. + //fprintf(stderr, "__gg__initialize_variable %s setting initialize_e\n", var->name); + var->attr |= initialized_e; + + // We need to make sure that the program_states vector has at least one + // entry in it. This happens when we are the very first PROGRAM-ID called + // in this module. + + // When there is no DATA DIVISION, program_states will be empty the first time + // we arrive here. + if( program_states.empty() ) + { + initialize_program_state(); + } + + char *local_initial = as_initial(var->initial); + + if( var->level == LEVEL88 ) + { + // We need to convert the options to the internal native codeset + + size_t buffer_size = 4; + char *buffer = (char *)malloc(buffer_size); + + size_t index = 0; + + cblc_field_t *parent = var->parent; + switch(parent->type) + { + case FldGroup: + case FldAlphanumeric: + { + char *walker = local_initial; + while(*walker) + { + static size_t first_size = MINIMUM_ALLOCATION_SIZE; + static char *first = (char *)malloc(first_size); + static size_t last_size = MINIMUM_ALLOCATION_SIZE; + static char *last = (char *)malloc(last_size); + if( (*walker & 0xFF) == 0xFF ) + { + strcpy(first, walker); + } + else + { + raw_to_internal(&first, &first_size, walker, strlen(walker)); + } + walker += strlen(first) + 1; + + if( (*walker & 0xFF) == 0xFF ) + { + strcpy(last, walker); + } + else + { + raw_to_internal(&last, &last_size, walker, strlen(walker)); + } + walker += strlen(last) + 1; + while(index + strlen(first) + strlen(last) + 3 > buffer_size) + { + buffer_size *= 2; + buffer = (char *)realloc(buffer, buffer_size); + } + strcpy(buffer+index, first); + index += strlen(first) + 1; + strcpy(buffer+index, last); + index += strlen(last) + 1; + } + buffer[index++] = 0; + break; + } + } + if( index > 0 ) + { + buffer = (char *)realloc(buffer, index); + local_initial = buffer; + } + } + + // Next order of business: When the variable was allocated in + // parser_symbol_add(), only LEVEL 01 variables had memory allocated. All + // child variables were given NULL data pointers. It is at this point that + // we apply offsets: + + cblc_field_t *parent = var->parent; + if( !var->data ) + { + + // We don't have any data. If our immediate parent does have data, then + // we can calculate our data+offset from his data+offset: + + if( parent && parent->data ) + { + var->data = parent->data - parent->offset + var->offset; + } + } + + if( !var->data ) + { + // This can happen with BASED variables before they are allocated + return; + } + + if( !(var->attr & based_e) && (var->attr & external_e) ) + { + // These types can't be initialized + return; + } + + // There are times, for example, when we are table with OCCURS, that we + // look like a variable with no initial, and we might be tempted to set our + // memory to the default. But if a parent has been initialized, we must not + // touch our memory: + bool a_parent_initialized = false; + if( var->data && !explicitly ) + { + while(parent) + { + if( strlen(as_initial(parent->initial)) ) + { + a_parent_initialized = true; + } + if( parent->level == LEVEL01 + || parent->level == LEVEL77) + { + break; + } + parent = parent->parent; // I can't help it. This just tickles me. + } + } + + if( is_redefined || a_parent_initialized || var->level == LEVEL66 || var->level == LEVEL88) + { + // Don't initialize variables that have the REDEFINES clause. Many things + // in COBOL programs don't work if you do, in particular the initialization + // of tables. + + // Likewise, don't initialize variables with an OCCURS clause. To do so + // means that we will likely clobber the values in the flat data item we + // effectively redefine. + return; + } + + // This is a little brutish, but it is nonetheless simple, effective, and + // not at all costly. The numeric-edited variable type can have a + // BLANK WHEN ZERO clause, which causes the storage to be set to spaces + // when receiving a value of zero. But according to the ISO/IEC 1989:2014 + // specification, section 13.18.63.3 sentence 8, initialization is not + // affected by any BLANK WHEN ZERO clause. + + // So, I am going to rather ham-handedly turn that bit off here, and + // restore it when initialization is done. + + // Save this for later + int save_the_attribute = var->attr; + + // Turn off the bit in question + var->attr &= ~blank_zero_e; + + size_t capacity = var->capacity ; + + size_t number_of_dimensions = 0; + size_t limits[MAXIMUM_TABLE_DIMENSIONS]; + size_t capacities[MAXIMUM_TABLE_DIMENSIONS]; + size_t dimension[MAXIMUM_TABLE_DIMENSIONS+1]; + + bool there_can_be_more = nsubscripts == 0; + if( nsubscripts == 0 ) + { + cblc_field_t *family_tree = var; + while(family_tree && number_of_dimensions < MAXIMUM_TABLE_DIMENSIONS) + { + if( family_tree->occurs_upper ) + { + limits[number_of_dimensions] = family_tree->occurs_upper; + capacities[number_of_dimensions] = family_tree->capacity; + dimension[number_of_dimensions] = 0; + number_of_dimensions += 1; + } + + family_tree = family_tree->parent; + } + + switch( var->type ) + { + case FldIndex: + case FldGroup: + case FldClass: + there_can_be_more = false; + break; + default: + break; + } + } + + // We need to save the location in case we start changing the location + // to handle initializing table elements: + unsigned char *save_the_location = var->data; + bool there_is_more = false; + unsigned char *outer_location; + if( nsubscripts ) + { + outer_location = qual_data; + } + else + { + outer_location = var->data; + } + do + { + var->data = outer_location; + switch( var->type ) + { + case FldGroup: + case FldAlphanumeric: + case FldAlphaEdited: + case FldNumericEdited: + case FldLiteralA: + { + // Any initialization values were converted to single-byte-coding in the + // right codeset during parser_symbol_add() + if( var->initial ) + { + memcpy(outer_location, var->initial, var->capacity); + } + else + { + if( !defaultbyte_in_play ) + { + memset( outer_location, + internal_space, + capacity ); + } + else + { + memset( outer_location, + defaultbyte, + capacity ); + } + } + break; + } + + case FldNumericDisplay: + { + // Any initialization values were converted to single-byte-coding in the + // right codeset during parser_symbol_add() + if( var->initial ) + { + memcpy(outer_location, var->initial, var->capacity); + } + else + { + if( !defaultbyte_in_play ) + { + memset( outer_location, + internal_zero, + capacity ); + if( (var->attr & signable_e) && (var->attr & separate_e) ) + { + if( var->attr & leading_e ) + { + outer_location[0] = internal_plus; + } + else + { + outer_location[var->capacity-1] = internal_plus; + } + } + } + else + { + memset( outer_location, + defaultbyte, + capacity ); + } + } + break; + } + + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldIndex: + case FldFloat: + { + // During parser_symbol_add(), the original text initial value was turned + // into the appropriate binary value. + if( var->initial ) + { + memcpy(outer_location, var->initial, var->capacity); + } + else + { + if( !defaultbyte_in_play ) + { + memset( outer_location, + 0, + capacity ); + } + else + { + memset( outer_location, + defaultbyte, + capacity ); + } + } + break; + } + + case FldLiteralN: + break; + + case FldClass: + // Do nothing for class + break; + + case FldPointer: + memset(var->data, 0, var->capacity); + break; + + default: + fprintf(stderr, "###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); + fprintf(stderr, "###### You got yourself a new CVT_type %d for variable %s (%s)\n", + var->type, + var->name, + local_initial); + __gg__abort("Unknown variable type"); + } + + char *location = (char *)save_the_location; + + there_is_more = false; + size_t i=0; + // Roll up through the dimensions like an odometer. + for(i=0; idata = save_the_location; + + // See the comment up above about suppressing and restoring + // BLANK WHEN ZERO during initialization. + var->attr |= (save_the_attribute&blank_zero_e); + } + +extern "C" +void +__gg__initialize_variable(cblc_field_t *var, + size_t offset, + int flag_bits) + { + init_var_both( var, + var->data + offset, + flag_bits); + } + +extern "C" +void +__gg__initialize_variable_clean(cblc_field_t *var, int flag_bits) + { +// if( var->type == FldLiteralA ) +// { +// fprintf(stderr, "BAZINGA!\n"); +// } + + init_var_both( var, + var->data, + flag_bits); + } + +static void +alpha_to_alpha_move_from_location(cblc_field_t *field, + size_t dest_offset, + size_t dest_length, + const char * source_location, + size_t source_length, + bool move_all) + { + // This is a helper function, called when it is known that both source + // and dest are alphanumeric + dest_length = dest_length ? dest_length : field->capacity; + + char *to = (char *)field->data + dest_offset; + const char *from = source_location; + size_t count = std::min(dest_length, source_length); + + if( source_length >= dest_length ) + { + // We have more source characters than places to put them + if( field->attr & rjust_e ) + { + // Destination is right-justified, so we + // discard the leading source characters: + memmove(to, + from + (source_length - count), + count); + } + else + { + // Destination is right-justified, so we + // discard the trailing source characters: + memmove(to, + from, + count); + } + } + else + { + // We have too few source characters to fill the destination. + if( field->attr & rjust_e ) + { + // The destination is right-justified + if( move_all ) + { + // This does "BOBBO" + size_t isource = 0; + for(size_t i=0; i= source_length ) + { + isource = 0; + } + } + } + else + { + // The destination is right-justified, and the source is an + // ordinary string too short to fill it. So, we space-fill + // the leading characters. + // We do the move first, in case this is an overlapping move + // involving characters that will be space-filled + memmove(to + (dest_length-count), + from, + count); + memset(to, internal_space, dest_length-count); + } + } + else + { + // The source is smaller than the destination + // The destination is left-justified + if( move_all ) + { + // and the source is move_all. We will repeat the input until + // it fills the output, starting from the left side. + size_t isource = 0; + for(size_t i=0; i= source_length ) + { + isource = 0; + } + } + } + else + { + // The destination is right-justified, and the source is an + // ordinary string too short to fill it. So, we space-fill + // the trailing characters. + // We do the move first, in case this is an overlapping move + // involving characters that will be space-filled + memmove(to, + from, + count); + memset( to + count, + internal_space, + dest_length-count); + } + } + } + } + +static void +alpha_to_alpha_move(cblc_field_t *dest, + size_t dest_offset, + size_t dest_size, + cblc_field_t *source, + size_t source_offset, + size_t source_size, + bool source_move_all) + { + alpha_to_alpha_move_from_location( dest, + dest_offset, + dest_size, + (char *)(source->data + source_offset), + source_size, + source_move_all); + } + +extern "C" +void +__gg__psz_to_alpha_move( cblc_field_t *field, + size_t offset, + size_t length, + const char *source, + size_t source_length ) + { + alpha_to_alpha_move_from_location( field, + offset, + length, + source, + source_length, + false); + } + +extern "C" +int +__gg__move( cblc_field_t *fdest, + size_t dest_offset, + size_t dest_size, + cblc_field_t *fsource, + size_t source_offset, + size_t source_size, + int source_flags, + cbl_round_t rounded ) + { + int size_error = 0; // This is the return value + + bool moved = true; + + __int128 value; + int rdigits; + + size_t min_length; + + cbl_figconst_t source_figconst = + (cbl_figconst_t)(fsource->attr & FIGCONST_MASK); + cbl_field_type_t dest_type = (cbl_field_type_t)fdest->type; + cbl_field_type_t source_type = (cbl_field_type_t)fsource->type; + + if( var_is_refmod(fdest) ) + { + // one or both are refmods, + dest_type = FldAlphanumeric; + if( source_figconst == normal_value_e ) + { + source_type = FldAlphanumeric; + } + } + + if( ( source_figconst == low_value_e + || source_figconst == space_value_e + || source_figconst == quote_value_e + || source_figconst == high_value_e ) + && + ( fdest->type == FldNumericBinary + || fdest->type == FldPacked + || fdest->type == FldNumericBin5 + || fdest->type == FldNumericDisplay + || fdest->type == FldFloat ) + ) + { + // Regardless of what you see below, as time went on it became clear that + // high-value and low-value required special processing in order to cope + // with code. Or, at least, to cope with legacy tests. + + // The ISO 2014 specification has this to say about the moving of figurative + // constants to numerics: + + // 14.9.24.3, paragraph 7) + + /* NOTE: MOVE of the figurative constant QUOTE or QUOTES to a numeric data + * item is an obsolete feature and is to be removed from the next edition + * of standard COBOL. MOVE of figurative constants that are not numeric, + * other than QUOTE or QUOTES, to a numeric item is an archaic feature of + * standard COBOL and its use should be avoided + */ + + int special_char; + if( source_figconst == low_value_e ) + { + special_char = ascii_to_internal(__gg__low_value_character); + } + else if( source_figconst == high_value_e ) + { + special_char = ascii_to_internal(__gg__high_value_character); + } + else if( source_figconst == quote_value_e ) + { + special_char = ascii_to_internal(__gg__quote_character); + } + else if( source_figconst == space_value_e ) + { + special_char = ascii_to_internal(ascii_space); + } + memset( fdest->data + dest_offset, + special_char, + dest_size); + } + else + { + switch( dest_type ) + { + case FldGroup: + switch( source_type ) + { + // For all other types, we just do a straight byte-for-byte move + case FldAlphanumeric: + case FldNumericEdited: + case FldAlphaEdited: + case FldNumericDisplay: + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldGroup: + // This is a little bold, but non-alphabetics will never + // have the rjust_e or MOVE_ALL bits on, so it's safe + // enough. + alpha_to_alpha_move(fdest, + dest_offset, + dest_size, + fsource, + source_offset, + source_size, + !!(source_flags & REFER_T_MOVE_ALL)); + break; + + default: + moved = false; + break; + } + + break; + + case FldAlphanumeric: + { + switch( source_type ) + { + case FldGroup: + alpha_to_alpha_move(fdest, + dest_offset, + dest_size, + fsource, + source_offset, + source_size, + !!(source_flags & REFER_T_MOVE_ALL)); + break; + + case FldAlphanumeric: + case FldNumericEdited: + case FldAlphaEdited: + // This is an ordinary alpha-to-alpha move: + alpha_to_alpha_move(fdest, + dest_offset, + dest_size, + fsource, + source_offset, + source_size, + !!(source_flags & REFER_T_MOVE_ALL)); + break; + + case FldNumericDisplay: + // We are moving a FldNumericDisplay to an alphanumeric: + if( fsource->rdigits > 0 ) + { + fprintf(stderr, "%s() %s:%d -- It isn't legal to move a" + " non-integer NumericDisplay to an" + " alphanumeric\n", + __func__, __FILE__, __LINE__); + fprintf( stderr, + "%s to %s\n", + fsource->name, + fdest->name); + abort(); + } + else + { + // We are moving a integer NumericDisplay to an + // alphanumeric. We ignore any sign bit, and just + // move the characters: + + int rdigits; + __int128 value; + + size_t source_digits + = fsource->digits + + ( fsource->rdigits < 0 + ? -fsource->rdigits : 0) ; + + // Pick up the absolute value of the source + value = __gg__binary_value_from_qualified_field(&rdigits, + fsource, + source_offset, + source_size); + + char ach[128]; + + // Convert it to the full complement of digits available + // from the source...but no more + __gg__binary_to_string_internal(ach, source_digits, value); + + if( !(fdest->attr & rjust_e) ) + { + min_length = std::min( source_digits, + dest_size); + memmove(fdest->data + dest_offset, ach, min_length); + if( min_length < dest_size ) + { + // min_length is smaller than dest_length, so we + // have to space-fill the excess bytes in the + // destination: + memset( fdest->data + dest_offset + min_length, + internal_space, + dest_size - min_length ); + } + } + else + { + // Destination is right-justified, so things are + // slightly more complex + if( source_digits >= dest_size ) + { + // We need to truncate the source data on the + // left: + memmove( + fdest->data + dest_offset, + ach + (source_digits - dest_size), + dest_size ); + } + else + { + // We need to move the shorty source string to + // the right side of the destination, and space-fill + // the prefix: + memmove(fdest->data + dest_offset + (dest_size - source_digits), + ach, + source_digits ); + memset( fdest->data + dest_offset, + internal_space, + dest_size - source_digits); + } + } + } + break; + + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldLiteralN: + // We are moving a binary number to an alphanumeric: + if( fsource->rdigits > 0 ) + { + fprintf(stderr, "%s() %s:%d -- It isn't legal to move a" + " non-integer binary number to an" + " alphanumeric\n", + __func__, __FILE__, __LINE__); + fprintf(stderr, "%s to %s\n", fsource->name, fdest->name); + abort(); + } + else + { + char ach[128]; + + // Turn the integer source into a value: + value = __gg__binary_value_from_qualified_field(&rdigits, + fsource, + source_offset, + source_size); + + source_size = fsource->digits; + + // Turn the integer value into a string: + __gg__binary_to_string_internal(ach, + source_size, + value); + + char *pach = ach; + + // When source is a temporary variable, it was set to + // a large number of digits, which will give the wrong + // result. So, we will make like the US Marine Corp, + // and improvise, adapt, and overcome. + + // Specifically, we'll move pach to point to the first + // character that isn't zero. + + if( fsource->attr & intermediate_e ) + { + while(source_size > 1) // This ensures we leave one '0' + { + if( *(pach+1) == '\0' ) + { + break; + } + if( ((*pach)&0xFF) != internal_zero ) + { + break; + } + pach += 1; + source_size -= 1; + } + } + + if( !(fdest->attr & rjust_e) ) + { + min_length = std::min( source_size, + dest_size); + memmove(fdest->data+dest_offset, pach, min_length); + if( min_length < dest_size ) + { + // min_length is smaller than dest_length, so we have to + // space-fill the excess bytes in the destination: + memset( fdest->data+dest_offset + min_length, + internal_space, + dest_size - min_length ); + } + } + else + { + // Destination is right-justified, so things are slightly more complex + if( source_size >= dest_size ) + { + // We need to truncate the source data on the left: + memmove(fdest->data+dest_offset, + pach + (source_size - dest_size), + dest_size ); + } + else + { + // We need to move the shorty source string to the + // right side of the destination, and space-fill the prefix: + memmove(fdest->data+dest_offset + (dest_size - source_size), + pach, + source_size ); + memset(fdest->data+dest_offset, internal_space, (dest_size - source_size)); + } + } + } + break; + + case FldIndex: + { + char ach[128]; + + // Turn the integer source into a value: + value = __gg__binary_value_from_qualified_field(&rdigits, + fsource, + source_offset, + source_size); + sprintf(ach, "%lu", (size_t)value); + + char *pach = ach; + + if( !(fdest->attr & rjust_e) ) + { + min_length = std::min( source_size, + dest_size); + memmove(fdest->data+dest_offset, pach, min_length); + if( min_length < dest_size ) + { + // min_length is smaller than dest_length, so we have to + // space-fill the excess bytes in the destination: + memset( fdest->data+dest_offset + min_length, + internal_space, + dest_size - min_length ); + } + } + else + { + // Destination is right-justified, so things are slightly more complex + if( source_size >= dest_size ) + { + // We need to truncate the source data on the left: + memmove(fdest->data+dest_offset, + pach + (source_size - dest_size), + dest_size ); + } + else + { + // We need to move the shorty source string to the + // right side of the destination, and space-fill the prefix: + memmove(fdest->data+dest_offset + (dest_size - source_size), + pach, + source_size ); + memset(fdest->data+dest_offset, internal_space, (dest_size - source_size)); + } + } + } + break; + + default: + moved = false; + break; + } + break; + } + + case FldNumericBinary: + { + switch( source_type ) + { + case FldGroup: + min_length = std::min(source_size, dest_size); + memmove(fdest->data+dest_offset, fsource->data+source_offset, min_length); + if( min_length < dest_size ) + { + // min_length is smaller than dest_length, so we have to + // space-fill the excess bytes in the destination: + memset( fdest->data+dest_offset + min_length, + internal_space, + dest_size - min_length ); + } + fdest->attr &= ~FIGCONST_MASK; + break; + + case FldAlphanumeric: + case FldNumericDisplay: + case FldNumericEdited: + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldIndex: + case FldLiteralN: + { + // We are moving a number to a number: + value = __gg__binary_value_from_qualified_field(&rdigits, + fsource, + source_offset, + source_size); + + if( truncation_mode == trunc_std_e ) + { + // We need to adjust the value to have the rdigits of the + // the destination: + + int scaler = rdigits - fdest->rdigits; + if( scaler > 0 ) + { + value /= __gg__power_of_ten(scaler); + rdigits -= scaler; + } + else if( scaler < 0 ) + { + value *= __gg__power_of_ten(-scaler); + rdigits -= scaler; + } + if( value < 0 ) + { + value = -value; + value %= __gg__power_of_ten(fdest->digits); + value = -value; + } + else + { + value %= __gg__power_of_ten(fdest->digits); + } + } + + __gg__int128_to_qualified_field( + fdest, + dest_offset, + dest_size, + value, + rdigits, + rounded, + &size_error ); + break; + } + + case FldFloat: + { + rdigits = get_scaled_rdigits(fdest); + bool negative = false; + __int128 value=0; + switch(fsource->capacity) + { + case 4: + { + _Float32 val = *(_Float32 *)(fsource->data+source_offset); + if(val < 0) + { + negative = true; + val = -val; + } + val *= (_Float32)__gg__power_of_ten(rdigits); + value = (__int128)val; + break; + } + case 8: + { + _Float64 val = *(_Float64 *)(fsource->data+source_offset); + if(val < 0) + { + negative = true; + val = -val; + } + val *= (_Float32)__gg__power_of_ten(rdigits); + value = (__int128)val; + break; + } + case 16: + { + //_Float128 val = *(_Float128 *)(fsource->data+source_offset); + _Float128 val; + memcpy(&val, fsource->data+source_offset, 16); + if(val < 0) + { + negative = true; + val = -val; + } + val *= (_Float32)__gg__power_of_ten(rdigits); + value = (__int128)val; + break; + } + } + if( negative ) + { + value = -value; + } + __gg__int128_to_qualified_field( + fdest, + dest_offset, + dest_size, + value, + rdigits, + rounded, + &size_error ); + break; + } + + default: + { + moved = false; + break; + } + } + break; + } + + case FldNumericDisplay: + case FldNumericEdited: + case FldNumericBin5: + case FldPacked: + case FldIndex: + // Bin5 and Index are treated with no truncation, as if they were + // trunc_bin_e. The other types aren't subject to truncation. + switch( source_type ) + { + case FldGroup: + min_length = std::min(source_size, dest_size); + memmove(fdest->data+dest_offset, fsource->data+source_offset, min_length); + if( min_length < dest_size ) + { + // min_length is smaller than dest_length, so we have to + // space-fill the excess bytes in the destination: + memset( fdest->data+dest_offset + min_length, + internal_space, + dest_size - min_length ); + } + break; + + case FldAlphanumeric: + case FldNumericDisplay: + case FldNumericEdited: + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldIndex: + case FldLiteralN: + { + // We are moving a number to a number: + value = __gg__binary_value_from_qualified_field(&rdigits, + fsource, + source_offset, + source_size); + __gg__int128_to_qualified_field( + fdest, + dest_offset, + dest_size, + value, + rdigits, + rounded, + &size_error ); + break; + } + + case FldFloat: + { + // We are converted a floating-point value fixed-point + + rdigits = get_scaled_rdigits(fdest); + _Float128 value=0; + switch(fsource->capacity) + { + case 4: + { + value = *(_Float32 *)(fsource->data+source_offset); + break; + } + case 8: + { + value = *(_Float64 *)(fsource->data+source_offset); + break; + } + case 16: + { + // value = *(_Float128 *)(fsource->data+source_offset); + memcpy(&value, fsource->data+source_offset, 16); + break; + } + } + __gg__float128_to_qualified_field( + fdest, + dest_offset, + value, + rounded, + &size_error); + break; + } + + default: + moved = false; + break; + } + break; + + case FldAlphaEdited: + { + switch( source_type ) + { + case FldGroup: + min_length = std::min(source_size, dest_size); + memmove(fdest->data+dest_offset, fsource->data+source_offset, min_length); + if( min_length < dest_size ) + { + // min_length is smaller than dest_length, so we have to + // space-fill the excess bytes in the destination: + memset( fdest->data+dest_offset + min_length, + internal_space, + dest_size - min_length ); + } + break; + + case FldNumericDisplay: + { + int rdigits; + __int128 value; + + int source_digits = fsource->digits + (fsource->rdigits<0 ? -fsource->rdigits : 0) ; + + // Pick up the absolute value of the source + value = __gg__binary_value_from_qualified_field(&rdigits, + fsource, + source_offset, + source_size); + char ach[64]; + + // Convert it to the full complement of digits available + // from the source...but no more + __gg__binary_to_string(ach, source_digits, value); + + // Binary to string returns ASCII characters: + for(int i=0; idata+dest_offset), + ach, + source_digits, + fdest->picture); + break; + } + + default: + { + static size_t display_string_size = MINIMUM_ALLOCATION_SIZE; + static char *display_string = (char *)malloc(display_string_size); + + size_t display_string_length = dest_size; + __gg__realloc_if_necessary( &display_string, + &display_string_size, + display_string_length); + + if( source_figconst == low_value_e ) + { + memset(display_string, ascii_to_internal(__gg__low_value_character), dest_size); + } + else if( source_figconst == zero_value_e ) + { + memset(display_string, internal_zero, dest_size); + } + else if( source_figconst == space_value_e ) + { + memset(display_string, internal_space, dest_size); + } + else if( source_figconst == quote_value_e ) + { + memset(display_string, ascii_to_internal(__gg__quote_character), dest_size); + } + else if( source_figconst == high_value_e ) + { + memset(display_string, ascii_to_internal(__gg__high_value_character), dest_size); + } + else + { + display_string = format_for_display_internal( + &display_string, + &display_string_size, + fsource, + (unsigned char *)(fsource->data+source_offset), + source_size, + source_flags && REFER_T_ADDRESS_OF); + display_string_length = strlen(display_string); + } + __gg__string_to_alpha_edited( (char *)(fdest->data+dest_offset), + display_string, + display_string_length, + fdest->picture); + break; + } + } + break; + } + + case FldFloat: + { + switch( source_type ) + { + case FldAlphanumeric: + { + char ach[256]; + size_t len = std::min(source_size, sizeof(ach)-1); + memcpy(ach, fsource->data+source_offset, len); + ach[len] = '\0'; + __gg__internal_to_console_in_place(ach, len); + switch( fdest->capacity ) + { + case 4: + { + *(float *)(fdest->data+dest_offset) = strtof32(ach, NULL); + break; + } + case 8: + { + *(double *)(fdest->data+dest_offset) = strtof64(ach, NULL); + break; + } + case 16: + { + //*(_Float128 *)(fdest->data+dest_offset) = strtof128(ach, NULL); + _Float128 t = strtof128(ach, NULL); + memcpy(fdest->data+dest_offset, &t, 16); + break; + } + break; + } + break; + } + default: + moved = false; + break; + } + break; + } + + default: + moved = false; + break; + } + if( !moved ) + { + fprintf(stderr, "%s() %s:%d -- We were unable to do a move from " + "type %d to %d\n", + __func__, __FILE__, __LINE__, + fsource->type, fdest->type); + abort(); + } + } + return size_error; + } + +extern "C" +int +__gg__move_literala(cblc_field_t *field, + size_t field_offset, + size_t field_size, + cbl_round_t rounded_, + const char *str, + size_t strlen ) + { + cbl_round_t rounded = static_cast(rounded_ & ~REFER_ALL_BIT); + bool move_all = !!(rounded_ & REFER_ALL_BIT); + + int size_error = 0; // This is the return value + + bool moved = true; + + __int128 value; + int rdigits; + + cbl_field_type_t dest_type = (cbl_field_type_t)field->type; + if( var_is_refmod(field) ) + { + dest_type = FldAlphanumeric; + } + + switch( dest_type ) + { + case FldGroup: + case FldAlphanumeric: + { + alpha_to_alpha_move_from_location(field, field_offset, field_size, str, strlen, move_all); + break; + } + + case FldNumericBinary: + { + value = __gg__dirty_to_binary_internal( str, + strlen, + &rdigits ); + if( truncation_mode == trunc_std_e ) + { + // We need to adjust the value to have the rdigits of the + // the destination: + + int scaler = rdigits - field->rdigits; + if( scaler > 0 ) + { + value /= __gg__power_of_ten(scaler); + rdigits -= scaler; + } + else if( scaler < 0 ) + { + value *= __gg__power_of_ten(-scaler); + rdigits -= scaler; + } + + if( value < 0 ) + { + value = -value; + value %= __gg__power_of_ten(field->digits); + value = -value; + } + else + { + value %= __gg__power_of_ten(field->digits); + } + } + __gg__int128_to_qualified_field( + field, + field_offset, + field_size, + value, + rdigits, + rounded, + &size_error ); + break; + } + + case FldNumericDisplay: + case FldNumericEdited: + case FldNumericBin5: + case FldPacked: + case FldIndex: + // Bin5 and Index are treated with no truncation, as if they were + // trunc_bin_e. The other types aren't subject to truncation. + // We are moving a number to a number: + value = __gg__dirty_to_binary_internal( str, + strlen, + &rdigits ); + __gg__int128_to_qualified_field( + field, + field_offset, + field_size, + value, + rdigits, + rounded, + &size_error ); + break; + + case FldAlphaEdited: + { + static size_t display_string_size = MINIMUM_ALLOCATION_SIZE; + static char *display_string = (char *)malloc(display_string_size); + + __gg__realloc_if_necessary( &display_string, + &display_string_size, + field_size); + + memset(display_string, internal_space, display_string_size); + size_t len = std::min(display_string_size, strlen); + memcpy(display_string, str, len); + __gg__string_to_alpha_edited( (char *)(field->data+field_offset), + display_string, + field_size, + field->picture); + break; + } + + case FldFloat: + { + char ach[256]; + size_t len = std::min(strlen, sizeof(ach)-1); + memcpy(ach, str, len); + ach[len] = '\0'; + switch( field->capacity ) + { + case 4: + { + *(float *)(field->data+field_offset) = strtof32(ach, NULL); + break; + } + case 8: + { + *(double *)(field->data+field_offset) = strtof64(ach, NULL); + break; + } + case 16: + { + _Float128 t = strtof128(ach, NULL); + memcpy(field->data+field_offset, &t, 16); + break; + } + break; + } + break; + } + + default: + moved = false; + break; + } + + if( !moved ) + { + fprintf(stderr, "%s() %s:%d -- We were unable to do a move to " + "type %d\n", + __func__, __FILE__, __LINE__, + field->type); + abort(); + } + + return size_error; + } + +extern "C" +void +__gg__file_sort_ff_input( cblc_file_t *workfile, + cblc_file_t *input) + { + // The name means "file-file input" + + // We are going to read records from input and write them to workfile. These + // files are already open. + + for(;;) + { + // Read the data from the input file into its record_area + __gg__file_read(input, + -1); + if( input->io_status >= FhNotOkay ) + { + break; + } + // We have the data we need. Transmit it to workfile. + int before_advancing = 0; + if( workfile->org == file_line_sequential_e ) + { + // we need a newline at the end of each line + before_advancing = 1; + } + else if( workfile->org == file_sequential_e ) + { + // We don't want any vertical movement + before_advancing = -1; + } + + size_t bytes_to_write = std::min( workfile->record_area_max, + input->record_area_max ); + + __gg__file_write( workfile, + input->default_record->data, + bytes_to_write, + 0, + before_advancing, + 0); // non-random + } + } + +extern "C" +void +__gg__file_sort_ff_output( cblc_file_t *output, + cblc_file_t *workfile) + { + // The name means "file-file output" + + // We read records from workfile and write them to the output file + + // Make sure workfile is positioned at the beginning + __gg__file_reopen(workfile, 'r'); + + for(;;) + { + __gg__file_read( workfile, + -1); + if( workfile->io_status >= FhNotOkay ) + { + break; + } + int advancing = -1; // Default to no vertical movement + if( output->org == file_line_sequential_e ) + { + advancing = 1; + } + + __gg__file_write( output, + workfile->default_record->data, + workfile->record_area_max, + 0, + advancing, + 0); // 1 would be is_random + } + } + +extern "C" +void +__gg__sort_workfile(cblc_file_t *workfile, + size_t nkeys, + cblc_field_t **keys, + size_t *ascending, + int duplicates) + { + // We are going to read the records of workfile into memory. We keep offsets + // into the memory buffer, and then we'll sort those offsets according to the + // things they point to. + + // The workfile is open and positioned at zero when we arrive here. + + // Read the file into memory + size_t buffer_size = 128; + unsigned char *contents = (unsigned char *)malloc(buffer_size); + size_t offset = 0; + std::vectoroffsets; + size_t bytes_read; + size_t bytes_to_write; + + for(;;) + { + __gg__file_read(workfile, + -1); + if( workfile->record_length ) + { + int rdigits; + bytes_read = (size_t) __gg__binary_value_from_field( + &rdigits, + workfile->record_length); + } + else + { + bytes_read = workfile->record_area_max; + } + if( workfile->io_status >= FhNotOkay ) + { + break; + } + + while( offset + sizeof(size_t) + bytes_read > buffer_size ) + { + buffer_size *= 2; + contents = (unsigned char *)realloc(contents, buffer_size); + } + offsets.push_back(offset); + + // Copy over the record size: + memcpy(contents+offset, &bytes_read, sizeof(size_t)); + offset += sizeof(size_t); + + // And the contents of the record + memcpy(contents+offset, workfile->default_record->data, bytes_read); + offset += bytes_read; + } + + sort_contents(contents, + offsets, + 0, + nkeys, + keys, + ascending, + duplicates); + + // We now put the sorted data back out onto the disk: + fclose(workfile->file_pointer); + __gg__file_reopen(workfile, 'w'); + + for(size_t i=0; iorg == file_line_sequential_e ) + { + advancing = 1; + } + if( workfile->record_area_min != workfile->record_area_max + && workfile->record_length ) + { + __gg__int128_to_field(workfile->record_length, + bytes_to_write, + 0, + truncation_e, + NULL); + } + __gg__file_write( workfile, + contents+offset, + bytes_to_write, + 0, + advancing, + 0); // 1 would be is_random + } + free(contents); + } + +extern "C" +void +__gg__merge_files( cblc_file_t *workfile, + size_t nkeys, + cblc_field_t **keys, + size_t *ascending, + size_t ninputs, + cblc_file_t **inputs) + { + // Merge takes in N files that are already sorted. It looks at the N records + // at the top of the N files, and figures out who the winner is, and puts each + // winner into workfile. If it notices that any of the files are not in the + // order specified by the keys it raises the EC-SORT-MERGE-SEQUENCE exception. + + // Is everybody ready? + + // Then we will begin. + + sorter.nkeys = nkeys; + sorter.keys = keys; + sorter.ascending = ascending; + + // We need to prime the pump by reading one record from everybody + size_t the_biggest = 0; + for(size_t i=0; irecord_area_max); + + __gg__file_read(inputs[i], + -1); + if( inputs[i]->io_status >= FhNotOkay ) + { + inputs[i] = NULL; + } + } + + // For each input, either there is a good record in its record area, or else + // inputs[i] for that file is NULL + + if( !the_biggest ) + { + return; + } + + unsigned char *prior_winner = (unsigned char *)malloc(the_biggest); + *prior_winner = '\0'; + + for(;;) + { + int winner = -1; + for(int i=0; i<(int)ninputs; i++ ) + { + if( !inputs[i] ) + { + // This input has been exhausted + continue; + } + if( winner == -1 ) + { + // Establish the first file as the current winner + winner = i; + continue; + } + // We now compare inputs[i] to the current winner + int ncompare = compare_two_records( inputs[i]->default_record->data, + inputs[winner]->default_record->data); + if( ncompare < 0 ) + { + // We have a new winner + winner = i; + } + } + // We have scanned all the inputs, looking for the smallest of them. + if( winner == -1 ) + { + // We have exhausted all of the inputs, which means we are done. + break; + } + if( *prior_winner ) + { + // We need to compare the current winner to the prior winner + int ncompare = compare_two_records( prior_winner, + inputs[winner]->default_record->data); + if( ncompare > 0 ) + { + // The prior winner is bigger than the current winner, which means that + // the input files were not in order. This is a run-time error. + + exception_raise(ec_sort_merge_sequence_e); + abort(); + } + } + // Establish winner as the prior_winner + memcpy( prior_winner, + inputs[winner]->default_record->data, + inputs[winner]->record_area_max); + // And send it to the workfile + + int before_advancing = -1; // No vertical movement... + if( workfile->org == file_line_sequential_e ) + { + // we need a newline at the end of each line sequential line + before_advancing = 1; + } + + __gg__file_write( workfile, + inputs[winner]->default_record->data, + inputs[winner]->record_area_max, + 0, + before_advancing, + 0); // 1 means is_random + + + // And now we need to replace the winner: + + __gg__file_read(inputs[winner], + -1); + if( inputs[winner]->io_status >= FhNotOkay ) + { + inputs[winner] = NULL; + } + } + + free(prior_winner); + } + +static const char * +funky_find( const char *piece, + const char *piece_end, + const char *whole, + const char *whole_end ) + { + const char *retval = NULL; + + size_t length_of_piece = piece_end - piece; + if(length_of_piece == 0) + { + __gg__abort("funky_find() length_of_piece shouldn't be zero"); + } + + whole_end -= length_of_piece; + + while( whole <= whole_end ) + { + if( memcmp( piece, whole, length_of_piece) == 0 ) + { + retval = whole; + break; + } + whole += 1; + } + return retval; + } + +static const char * +funky_find_backward(const char *piece, + const char *piece_end, + const char *whole, + const char *whole_end ) + { + const char *retval = NULL; + + size_t length_of_piece = piece_end - piece; + if(length_of_piece == 0) + { + __gg__abort("funky_find_backward() length_of_piece shouldn't be zero"); + } + + whole_end -= length_of_piece; + + while( whole <= whole_end ) + { + if( memcmp( piece, whole_end, length_of_piece) == 0 ) + { + retval = whole_end; + break; + } + whole_end -= 1; + } + return retval; + } + +typedef struct normalized_operand + { + // These are the characters of the string. When the field is NumericDisplay + // any leading or trailing +/- characters are removed, and any embedded + // NUMERIC_DISPLAY_SIGN_BIT bits are removed. + std::string the_characters; + size_t offset; // Usually zero. One when there is a leading sign. + size_t length; // Usually the same as the original. But it is one less + // // than the original when there is a trailing sign. + } normalized_operand; + +typedef struct comparand + { + size_t id_2_index; + cbl_inspect_bound_t operation; + normalized_operand identifier_3; // The thing to be found + normalized_operand identifier_5; // The replacement, for FORMAT 2 + const char *alpha; // The start location within normalized_id_1 + const char *omega; // The end+1 location within normalized_id_1 + size_t leading_count; + bool leading; + bool first; + } comparand; + +typedef struct id_2_result + { + cblc_field_t *id2; + size_t id2_o; + size_t id2_s; + size_t result; + } id_2_result; + +static normalized_operand +normalize_id( const cblc_field_t *refer, + size_t refer_o, + size_t refer_s + ) + { + normalized_operand retval; + + if( refer ) + { + unsigned char *data = refer->data + refer_o; + cbl_figconst_t figconst + = (cbl_figconst_t)(refer->attr & FIGCONST_MASK); + + retval.offset = 0; + retval.length = refer_s; + + if( refer->type == FldNumericDisplay ) + { + // The value is NumericDisplay. + if( refer->attr & separate_e ) + { + // Because the sign is a separate plus or minus, the length + // gets reduced by one: + retval.length = refer_s - 1; + if( refer->attr & leading_e ) + { + // Because the sign character is LEADING, we increase the + // offset by one + retval.offset = 1; + } + } + for( size_t i=retval.offset; i id_2_results(n_identifier_2); + + // Pick up identifier_1, which is the string being inspected + cblc_field_t *id1 = __gg__treeplet_1f[cblc_index]; + size_t id1_o = __gg__treeplet_1o[cblc_index]; + size_t id1_s = __gg__treeplet_1s[cblc_index]; + cblc_index += 1; + // normalize it, according to the language specification. + normalized_operand normalized_id_1 = normalize_id(id1, id1_o, id1_s); + + std::vector comparands; + + for(size_t i=0; i comparands[k].omega ) + { + // This can't be a match, because the rightmost + // character of the comparand falls to the right + // of the comparand's omega + continue; + } + if( rightmost + comparands[k].identifier_3.length > the_end_of_the_world ) + { + // This can't be a match, because the rightmost character of the + // comparand falls past the new edge of id_1 established by a prior + // match. + continue; + } + // A match is theoretically possible, because all + // the characters of the comparand fall between + // alpha and omega: + bool possible_match = true; + + if( comparands[k].operation != bound_characters_e ) + { + for(size_t m=0; m= comparands[k].alpha ) + { + for(size_t m=0; m id_2_results(n_identifier_2); + + // Pick up identifier_1, which is the string being inspected + cblc_field_t *id1 = __gg__treeplet_1f[cblc_index]; + size_t id1_o = __gg__treeplet_1o[cblc_index]; + size_t id1_s = __gg__treeplet_1s[cblc_index]; + cblc_index += 1; + // normalize it, according to the language specification. + normalized_operand normalized_id_1 + = normalize_id(id1, id1_o, id1_s); + + std::vector comparands; + + for(size_t i=0; i comparands[k].omega ) + { + // This can't be a match, because the rightmost + // character of the comparand falls to the right + // of the comparand's omega + continue; + } + // A match is theoretically possible, because all + // the characters of the comparand fall between + // alpha and omega: + bool possible_match = true; + + if( comparands[k].operation != bound_characters_e ) + { + for(size_t m=0; m comparands; + + // Pick up the count of operations: + size_t nbounds = integers[int_index++]; + + for(size_t j=0; jattr & FIGCONST_MASK ) + { + match_lengths( next_comparand.identifier_3, + next_comparand.identifier_5); + } + else if( id5->attr & FIGCONST_MASK ) + { + match_lengths( next_comparand.identifier_5, + next_comparand.identifier_3); + } + + next_comparand.alpha + = normalized_id_1.the_characters.c_str(); + next_comparand.omega + = next_comparand.alpha + normalized_id_1.length; + + normalized_operand normalized_id_4_before + = normalize_id(id4_before, id4_before_o, id4_before_s); + normalized_operand normalized_id_4_after + = normalize_id(id4_after, id4_after_o, id4_after_s); + + the_alpha_and_omega_backward( normalized_id_4_before, + normalized_id_4_after, + next_comparand.alpha, + next_comparand.omega); + next_comparand.leading = true; + next_comparand.leading_count = 0; + next_comparand.first = true; + comparands.push_back(next_comparand); + } + } + } + } + + const char *leftmost = normalized_id_1.the_characters.c_str(); + const char *rightmost = leftmost + normalized_id_1.length; + const char *the_end_of_the_world = rightmost; + + while( leftmost < rightmost ) + { + rightmost -= 1; + // We look at the rightmost position. If that position is within the + // alpha-to-omega qualified range, we check all possible matches: + + for(size_t k=0; k comparands[k].omega ) + { + // This can't be a match, because the rightmost + // character of the comparand falls to the right + // of the comparand's omega + continue; + } + if( rightmost + comparands[k].identifier_3.length > the_end_of_the_world ) + { + // This can't be a match, because the rightmost character of the + // comparand falls past the new edge of id_1 established by a prior + // match. + continue; + } + // A match is theoretically possible, because all + // the characters of the comparand fall between + // alpha and omega: + bool possible_match = true; + + if( comparands[k].operation != bound_characters_e ) + { + for(size_t m=0; m= comparands[k].alpha ) + { + for(size_t m=0; mdata + id1_o; + int index_dest = normalized_id_1.offset; + if( id1->type == FldNumericDisplay ) + { + for(size_t i=0; i comparands; + + // Pick up the count of operations: + size_t nbounds = integers[int_index++]; + + for(size_t j=0; jattr & FIGCONST_MASK ) + { + match_lengths( next_comparand.identifier_3, + next_comparand.identifier_5); + } + else if( id5->attr & FIGCONST_MASK ) + { + match_lengths( next_comparand.identifier_5, + next_comparand.identifier_3); + } + + next_comparand.alpha + = normalized_id_1.the_characters.c_str(); + next_comparand.omega + = next_comparand.alpha + normalized_id_1.length; + + normalized_operand normalized_id_4_before + = normalize_id(id4_before, id4_before_o, id4_before_s); + normalized_operand normalized_id_4_after + = normalize_id(id4_after, id4_after_o, id4_after_s); + + the_alpha_and_omega(normalized_id_4_before, + normalized_id_4_after, + next_comparand.alpha, + next_comparand.omega); + next_comparand.leading = true; + next_comparand.leading_count = 0; + next_comparand.first = true; + comparands.push_back(next_comparand); + } + } + } + } + + // We are now set up to accomplish the data flow described + // in the language specification. We loop through the + // the character positions in normalized_id_1: + const char *leftmost + = normalized_id_1.the_characters.c_str(); + const char *rightmost + = leftmost + normalized_id_1.length; + + while( leftmost < rightmost ) + { + // For each leftmost position, we check each of the + // comparands + + for(size_t k=0; k comparands[k].omega ) + { + // This can't be a match, because the rightmost + // character of the comparand falls to the right + // of the comparand's omega + continue; + } + // A match is theoretically possible, because all + // the characters of the comparand fall between + // alpha and omega: + bool possible_match = true; + if( comparands[k].operation != bound_characters_e) + { + for(size_t m=0; mdata + id1_o; + int index_dest = normalized_id_1.offset; + if( id1->type == FldNumericDisplay ) + { + for(size_t i=0; idata+replacement_offset), replacement_size); + } + + cbl_figconst_t figconst = + (cbl_figconst_t)(replacement->attr & FIGCONST_MASK); + if( figconst ) + { + size_t figchars = strlen(psz_input)+1; + __gg__realloc_if_necessary(&psz_figstring, &psz_figstring_size, figchars); + char figchar = '\0'; + switch( figconst ) + { + case normal_value_e: + abort(); + break; + case low_value_e : + figchar = __gg__low_value_character; + break; + case zero_value_e : + figchar = internal_0; + break; + case space_value_e : + figchar = internal_space; + break; + case quote_value_e : + figchar = ascii_to_internal(__gg__quote_character); + break; + case high_value_e : + figchar = __gg__high_value_character; + break; + case null_value_e: + break; + } + memset(psz_figstring, figchar, figchars-1); + psz_figstring[figchars] = '\0'; + psz_replacement = psz_figstring; + } + + // Use a simple map to make this O(N), rather than an O(N-squared), + // computational complexity + static const unsigned char map_init[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }; + unsigned char map[256]; + unsigned char replaced[256]; + + memcpy(map, map_init, 256); + memset(replaced, 0, 256); + + for(size_t i=0; idata+input_offset, psz_input, input_size); + } + +static void +move_string(cblc_field_t *field, + size_t offset, + size_t length, + const char *from, + size_t strlen_from = (size_t)(-1) ) + { + bool moved = true; + + if( strlen_from == (size_t)(-1) ) + { + strlen_from = strlen(from); + } + + switch(field->type) + { + case FldGroup: + case FldAlphanumeric: + case FldAlphaEdited: + { + char *to = (char *)(field->data + offset); + size_t dest_length = length ? length : field->capacity; + size_t source_length = strlen_from; + size_t count = std::min(dest_length, source_length); + + if( source_length >= dest_length ) + { + // We have more source characters than places to put them + if( field->attr & rjust_e ) + { + // Destination is right-justified, so we + // discard the leading source characters: + memmove(to, + from + (source_length - count), + count); + } + else + { + // Destination is right-justified, so we + // discard the trailing source characters: + memmove(to, + from, + count); + } + } + else + { + // We have too few source characters to fill the destination. + if( field->attr & rjust_e ) + { + // The destination is right-justified, and the source is an + // ordinary string too short to fill it. So, we space-fill + // the leading characters. + memmove(to + (dest_length-count), + from, + count); + memset(to, internal_space, dest_length-count); + } + else + { + // The destination is left-justified + // We do the move first, in case this is an overlapping move + // involving characters that will be space-filled + memmove(to, + from, + count); + memset( to + count, + internal_space, + dest_length-count); + } + } + break; + } + + case FldNumericBinary: + case FldPacked: + case FldNumericDisplay: + case FldNumericEdited: + case FldNumericBin5: + case FldIndex: + { + // We are starting with a string, and setting it to a numerical + // target. + int rdigits; + __int128 value = __gg__dirty_to_binary_internal( from, + strlen_from, + &rdigits); + __gg__int128_to_qualified_field(field, + offset, + length, + value, + rdigits, + truncation_e, + NULL); + break; + } + + default: + moved = false; + break; + } + if( !moved ) + { + fprintf(stderr, "%s() %s:%d -- We were unable move a string to " + "field type %d\n", + __func__, __FILE__, __LINE__, + field->type); + abort(); + } + } + +static char * +brute_force_trim(char *str) + { + char *retval = str; + while( *retval == internal_space ) + { + retval += 1; + } + char *p = retval + strlen(retval)-1; + while( p > retval && *p == internal_space ) + { + *p-- = NULLCH; + } + return retval; + } + +extern "C" +int +__gg__string(size_t integers[]) + { + // The first integer is the count of identifier-2 values. Call it N + // The following N integers are the counts of each of the identifier-1 values, + // one for each identifier-1. Call them M. + + // The first refer is the target + // The second refer is the pointer + // The third refer is identifier-2 for N1 + // That's followed by M1 identifier-1 values + // That's followed by identifier2 for N2 + // And so on + + cblc_field_t **ref = __gg__treeplet_1f; + size_t *ref_o = __gg__treeplet_1o; + size_t *ref_s = __gg__treeplet_1s; + + static const int INDEX_OF_POINTER = 1; + + size_t index_int = 0; + size_t index_cblc = 0 ; + + char figlow[2] = {ascii_to_internal(__gg__low_value_character), 0x00}; + char fighigh[2] = {ascii_to_internal(__gg__high_value_character), 0x00}; + char figzero[2] = {(char)internal_zero, 0x00}; + char figquote[2] = {ascii_to_internal(__gg__quote_character), 0x00}; + char figspace[2] = {(char)internal_space, 0x00}; + + if( __gg__high_value_character == DEGENERATE_HIGH_VALUE ) + { + fighigh[0] = __gg__high_value_character; + } + else + { + fighigh[0] = ascii_to_internal(__gg__high_value_character); + } + + // Pick up the number of identifier-2 values + size_t N = integers[index_int++]; + + // Pick up the target + cblc_field_t *tgt = ref[index_cblc]; + size_t tgt_o = ref_o[index_cblc]; + size_t tgt_s = ref_s[index_cblc]; + index_cblc += 1; + char *dest = (char *)(tgt->data + tgt_o); + ssize_t dest_length = tgt_s; + + // Skip over the index of POINTER: + index_cblc += 1; + + // Pick up the pointer, if any + ssize_t pointer = 0; + if( ref[INDEX_OF_POINTER] ) + { + int rdigits; + pointer = (size_t)__gg__binary_value_from_qualified_field( + &rdigits, + ref [INDEX_OF_POINTER], + ref_o[INDEX_OF_POINTER], + ref_s[INDEX_OF_POINTER] + ); + pointer -= 1; + } + + int overflow = 0; + + // Make sure that the destination pointer is within the destination + if( pointer >= 0 || pointer < dest_length ) + { + // We are go for looping through identifier-2 values: + + for( size_t i=0; iattr & FIGCONST_MASK) + : 0 ); + switch(figconst) + { + case low_value_e: + piece = figlow; + piece_end = piece + 1; + break; + case zero_value_e: + piece = figzero; + piece_end = piece + 1; + break; + case space_value_e: + piece = figspace; + piece_end = piece + 1; + break; + case quote_value_e: + piece = figquote; + piece_end = piece + 1; + break; + case high_value_e: + piece = fighigh; + piece_end = piece + 1; + break; + default: + piece = id2 ? (char *)(id2->data + id2_o) : NULL; + piece_end = id2 ? piece + id2_s : NULL; + break; + } + + for(size_t i=0; idata + id1_o): NULL ; + const char *whole_end = id1 ? whole + id1_s : NULL; + + // As usual, we need to cope with figurative constants: + cbl_figconst_t figconst = (cbl_figconst_t) ( id1 ? (id1->attr & FIGCONST_MASK) : 0 ); + switch( figconst ) + { + case low_value_e: + whole = figlow; + whole_end = whole + 1; + break; + case zero_value_e: + whole = figzero; + whole_end = whole + 1; + break; + case space_value_e: + whole = figspace; + whole_end = whole + 1; + break; + case quote_value_e: + whole = figquote; + whole_end = whole + 1; + break; + case high_value_e: + whole = fighigh; + whole_end = whole + 1; + break; + default: + break; + } + + if(piece) + { + const char *found = funky_find( piece, piece_end, + whole, whole_end); + if(found) + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" + char *wfound = (char *)found; +#pragma GCC diagnostic pop + whole_end = wfound; + } + } + while(whole < whole_end) + { + if(pointer >= dest_length) + { + overflow = 1; + break; + } + dest[pointer++] = *whole++; + } + if( overflow ) + { + break; + } + } + } + + // Update the pointer, if there is one + if( ref[INDEX_OF_POINTER] ) + { + __gg__int128_to_qualified_field(ref [INDEX_OF_POINTER], + ref_o[INDEX_OF_POINTER], + ref_s[INDEX_OF_POINTER], + (__int128)(pointer+1), + 0, + truncation_e, + NULL ); + } + } + else + { + // The initial pointer is not inside the destination + overflow = 1; + } + + return overflow; + } + +static +void +display_both(cblc_field_t *field, + unsigned char *qual_data, + size_t qual_size, + int flags, + int file_descriptor, + int advance ) + { + static size_t display_string_size = MINIMUM_ALLOCATION_SIZE; + static char *display_string = (char *)malloc(display_string_size); + + format_for_display_internal(&display_string, + &display_string_size, + field, + qual_data, + qual_size, + !!(flags & REFER_T_ADDRESS_OF) ); + + // Let's honor the locale of the system, as best we can: + static size_t converted_size = MINIMUM_ALLOCATION_SIZE; + static char *converted = (char *)malloc(converted_size); + + internal_to_console(&converted, &converted_size, display_string, strlen(display_string)); + + ssize_t ss = write( file_descriptor, + converted, + strlen(converted)); + if(ss == -1) + { + fprintf(stderr, "__gg__display() %s %p\n", field->name, qual_data); + fprintf(stderr, "__gg__display() %zd\n", converted_size); + fprintf(stderr, "__gg__display() "); + for(size_t i=0; idata + offset, + size ? size : field->capacity, + 0, + file_descriptor, + advance); + } + +extern "C" +void +__gg__display_clean(cblc_field_t *field, + int file_descriptor, + int advance ) + { + display_both( field, + field->data, + field->capacity, + 0, + file_descriptor, + advance); + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-result" + +extern "C" +void +__gg__display_string( int file_descriptor, + char *str, + size_t length, + int advance ) + { + // Let's honor the locale of the system, as best we can: + static size_t converted_size = MINIMUM_ALLOCATION_SIZE; + static char *converted = (char *)malloc(converted_size); + + size_t max_possible = 2 * length; + if( max_possible > converted_size ) + { + converted_size = max_possible; + converted = (char *)realloc(converted, converted_size); + } + + __gg__ascii_to_console(&converted, &converted_size, str, length); + + write( file_descriptor, + converted, + strlen(converted)); + if( advance ) + { + write( file_descriptor, + "\n", + 1); + } + } + +#pragma GCC diagnostic push + +static +char * +mangler_core(const char *s, const char *eos) + { + // The caller needs to be aware that the return value is a static character + // array. Program accordingly. + + // This is the run-time version of the code in cobol1.cc routine that mangles + // cobol names into workable form. The logic here has to match the logic + // there so that calls work. + + static char cobol_name[1024]; + + while( s < eos && *s == ascii_space ) + { + s += 1; + } + while( s < eos && *(eos-1) == ascii_space ) + { + eos -= 1; + } + + char *d = cobol_name; + if( s[0] >= ascii_0 && s[0] <= ascii_9 ) + { + *d++ = '_'; + } + + while(s < eos) + { + int ch = *s++; + if( ch == ascii_hyphen ) + { + *d++ = ascii_dollar_sign; + } + else + { + *d++ = tolower(ch); + } + } + *d++ = NULLCH; + + return cobol_name; + } + +static +char * +not_mangled_core(const char *s, const char *eos) + { + const char *s1 = s; + const char *s2 = eos; + bool has_dash = false; + + while( s < eos && *s == internal_space ) + { + s += 1; + } + while( s < eos && *(eos-1) == internal_space ) + { + eos -= 1; + } + + if( s[0] >= ascii_0 && s[0] <= ascii_9 ) + { + has_dash = true; + } + else + { + while(s < eos) + { + int ch = *s++; + if( ch == ascii_hyphen ) + { + has_dash = true; + } + } + } + + if( has_dash ) + { + return mangler_core(s1, s2); + } + + return (char *)s1; + } + +extern "C" +void +__gg__accept( enum special_name_t special_e, + cblc_field_t *field, + size_t offset, + size_t length) + { + int file_descriptor = 0; // Default to stdin + + size_t max_chars = length ? length : field->capacity; + + if( special_e == CONSOLE_e ) + { + // Welcome to the land of possibly screwball assumptions. If reading + // from CONSOLE/stdin it's possible that the target variable is + // a NumericBinary of length 4, which can hold a 10-digit number. So, + // we need room to accept the characters, which will later on be converted + // to a binary value. + + // But SYSIN and SYSIPT seem to require that characters be read until the + // size of the target variable is satisfied, which implies further that + // the target must be alphanumeric. + + // What reality will ultimately offer is unknown to me. But I'm doing + // the best I can with what I've got, and, right now, this is what + // I've got. + if( max_chars < 64 ) + { + // Set a floor for the length of the buffer. This will let us cope + // with, say, a four-byte binary value that can hold ten digits + max_chars = 64; + } + } + + char *buffer = (char *)malloc(max_chars+1); + memset(buffer, ascii_space, max_chars); + buffer[max_chars] = NULLCH; + size_t i = 0; + + for(;;) + { + char ch; + ssize_t bytes_read = read(file_descriptor, &ch, 1); + if( bytes_read <= 0 ) + { + // Error or end-of-file, so give up + break; + } + + if( ch == '\n' ) + { + // End-of-line + if( special_e == CONSOLE_e ) + { + // When reading from the console, a newline means that the + // typist pressed ENTER/RETURN, and the input is done. This is + // also the case even when stdin was redirected from a file or + // another process + break; + } + else + { + // But if SYSIN_e or SYSIPT_e was specified, we are emulating + // the universe of punched cards, so we just keep reading in + // characters until we have read in max_chars. We found it + // necessary to implement ACCEPT in this fashion to get the + // NIST test suite to work. + + // Note that in both cases, we keep reading until we hit + // an actual newline or end-of-file + + if( i >= max_chars ) + { + break; + } + continue; + } + } + if(i < max_chars) + { + buffer[i++] = ch; + } + } + + switch(field->type) + { + case FldGroup : + case FldAlphanumeric : + case FldAlphaEdited : + console_to_internal(buffer, i); + move_string(field, + offset, + length, + buffer, + strlen(buffer)); + break; + + case FldNumericDisplay: + { + // In the NIST tests, feeding ten digits 0123456789 into a + // PIC 9(9) results in a nine-digit 012345678 rather than our + // default 123456789 + + int digit_count = 0; + char *p = buffer; + while(*p && digit_count < field->digits) + { + if( *p == __gg__decimal_point ) + { + p += 1; + continue; + } + + switch(*p) + { + case ascii_0: + case ascii_1: + case ascii_2: + case ascii_3: + case ascii_4: + case ascii_5: + case ascii_6: + case ascii_7: + case ascii_8: + case ascii_9: + p += 1; + digit_count += 1; + continue; + break; + case ascii_minus: + case ascii_plus: + p += 1; + continue; + break; + default: + goto we_are_done; + break; + } + } +we_are_done: + *p = NULLCH; + + int rdigits; + __int128 value = __gg__dirty_to_binary_source( buffer, + (int)i, + &rdigits); + + __gg__int128_to_qualified_field(field, + offset, + length, + value, + rdigits, + truncation_e, + NULL); + break; + } + + default: + { + int rdigits; + + __int128 value = __gg__dirty_to_binary_source( buffer, + (int)i, + &rdigits); + + __gg__int128_to_qualified_field(field, + offset, + length, + value, + rdigits, + truncation_e, + NULL); + break; + } + } +#if LOGGING_FOR_TESTING + if( isatty(file_descriptor) ) + { + auto p = strchr(buffer, '\0'); + *p = '\n'; + write(1, buffer, (p - buffer) + 1); + } +#endif + free(buffer); + } + +extern "C" +__int128 +__gg__binary_value_from_field( int *rdigits, + cblc_field_t *var) + { + return get_binary_value_local( rdigits, + var, + var->data, + var->capacity); + } + +extern "C" +__int128 +__gg__binary_value_from_qualified_field(int *rdigits, + cblc_field_t *var, + size_t offset, + size_t size) + { + return get_binary_value_local( rdigits, + var, + var->data + offset, + size); + } + +extern "C" +_Float128 +__gg__float128_from_field( cblc_field_t *field ) + { + _Float128 retval=0; + if( field->type == FldFloat || field->type == FldLiteralN ) + { + retval = get_float128(field, field->data); + } + else + { + int rdigits; + retval = (_Float128)__gg__binary_value_from_field(&rdigits, field); + if( rdigits ) + { + retval /= (_Float128)__gg__power_of_ten(rdigits); + } + } + return retval; + } + +extern "C" +_Float128 +__gg__float128_from_qualified_field( cblc_field_t *field, size_t offset, size_t size) + { + _Float128 retval=0; + if( field->type == FldFloat || field->type == FldLiteralN ) + { + retval = get_float128(field, field->data+offset); + } + else + { + int rdigits; + retval = (_Float128)__gg__binary_value_from_qualified_field(&rdigits, field, offset, size); + if( rdigits ) + { + retval /= (_Float128)__gg__power_of_ten(rdigits); + } + } + return retval; + } + +extern "C" +__int128 +__gg__integer_from_qualified_field( cblc_field_t *var, + size_t var_offset, + size_t var_size) + { + // This is useful when a temporary value with some number of rdigits + // is passed when the value is known to be an integer + + int rdigits; + __int128 retval = get_binary_value_local( &rdigits, + var, + var->data + var_offset, + var_size); + if( rdigits ) + { + retval /= __gg__power_of_ten(rdigits); + } + return retval; + } + +extern "C" +void +__gg__int128_to_field(cblc_field_t *tgt, + __int128 value, + int source_rdigits, + enum cbl_round_t rounded, + int *compute_error) + { + int128_to_field(tgt, + tgt->data, + tgt->capacity, + value, + source_rdigits, + rounded, + compute_error); + } + +extern "C" +void +__gg__int128_to_qualified_field(cblc_field_t *tgt, + size_t offset, + size_t length, + __int128 value, + int source_rdigits, + enum cbl_round_t rounded, + int *compute_error) + { + int128_to_field(tgt, + tgt->data + offset, + length ? length : tgt->capacity, + value, + source_rdigits, + rounded, + compute_error); + } + +static __int128 +float128_to_int128( int *rdigits, + cblc_field_t *field, + _Float128 value, + cbl_round_t rounded, + int *compute_error) + { + __int128 retval = 0; + if( value == INFINITY ) + { + *compute_error = compute_error_overflow; + } + else if( value == NAN ) + { + *compute_error = compute_error_underflow; + } + else + { + // Our mission is to take a 128-bit floating point value and convert it + // to a 128-bit number. If we can't, we flag it appropriately. + + if( field->attr & intermediate_e ) + { + // Our target doesn't have a fixed number of rdigits. We will look at the + // value, and from that calculate the maximum number of rdigits we can + // get away with. + + // Calculate the number of digits to the left of the decimal point: + int digits = (int)(floorf128(logf128(fabsf128(value)))+1); + + // Make sure it is not a negative number + digits = std::max(0, digits); + + // From that we can calculate the number of rdigits + *rdigits = MAX_FIXED_POINT_DIGITS - digits; + } + else + { + // Our target has a fixed number of rdigits: + *rdigits = field->rdigits; + } + + // We now multiply our value by 10**rdigits, in order to make the + // floating-point value have the same magnitude as our target __int128 + + value *= powf128(10.0Q, (_Float128)(*rdigits)); + + // We are ready to cast value to an __int128. But this value could be + // too large to fit, which is an error condition we want to flag: + + if( fabsf128(value) >= 1.0E38Q ) + { + *compute_error = compute_error_overflow; + } + else + { + retval = f128_to_i128_rounded(rounded, value, compute_error); + } + } + + return retval; + } + +static void +float128_to_location( cblc_field_t *tgt, + unsigned char *data, + size_t size, + _Float128 value, + enum cbl_round_t rounded, + int *compute_error) + { + switch(tgt->type) + { + case FldFloat: + { + switch(tgt->capacity) + { + case 4: + if( fabsf128(value) == (_Float128)INFINITY + || fabsf128(value) > 3.4028235E38Q ) + { + if( compute_error ) + { + *compute_error |= compute_error_overflow; + } + if( value < 0 ) + { + *(float *)(data) = -INFINITY; + } + else + { + *(float *)(data) = INFINITY; + } + } + else + { + *(float *)(data) = (float)value; + } + break; + + case 8: + if( fabsf128(value) == (_Float128)INFINITY + || fabsf128(value) > 1.7976931348623157E308Q ) + { + if( compute_error ) + { + *compute_error |= compute_error_overflow; + } + if( value < 0 ) + { + *(double *)(data) = -INFINITY; + } + else + { + *(double *)(data) = INFINITY; + } + } + else + { + *(double *)(data) = (double)value; + } + break; + + case 16: + if( fabsf128(value) == (_Float128)INFINITY ) + { + if( compute_error ) + { + *compute_error |= compute_error_overflow; + } + } + + //*(_Float128 *)(data) = value; + memcpy(data, &value, 16); + break; + } + break; + } + + default: + { + if( compute_error ) + { + int digits; + if( tgt->attr & intermediate_e ) + { + digits = MAX_FIXED_POINT_DIGITS; + } + else + { + digits = tgt->digits; + } + + _Float128 maximum; + + if( digits ) + { + maximum = __gg__power_of_ten(digits); + } + + // When digits is zero, this is a binary value without a PICTURE string. + // we don't truncate in that case + if( digits && fabsf128(value) >= maximum ) + { + *compute_error |= compute_error_truncate; + } + } + + int rdigits=0; // Initialized to quiet a compiler warning. + __int128 val128 = float128_to_int128( &rdigits, + tgt, + value, + rounded, + compute_error); + int128_to_field(tgt, + data, + size, + val128, + rdigits, + rounded, + compute_error); + break; + } + } + } + + +extern "C" +void +__gg__float128_to_field(cblc_field_t *tgt, + _Float128 value, + enum cbl_round_t rounded, + int *compute_error) + { + float128_to_location( tgt, + tgt->data, + tgt->capacity, + value, + rounded, + compute_error); + } + +extern "C" +void +__gg__float128_to_qualified_field(cblc_field_t *tgt, + size_t tgt_offset, + _Float128 value, + enum cbl_round_t rounded, + int *compute_error) + { + float128_to_location( tgt, + tgt->data + tgt_offset, + tgt->capacity, + value, + rounded, + compute_error); + } + +extern "C" +bool +__gg__bitop(cblc_field_t *a, + bitop_t op, + size_t bitmask) + { + bool retval = false; + int rdigits; + __int128 value = __gg__binary_value_from_field(&rdigits, a); + switch(op) + { + case bit_set_op: // set bits on + value |= bitmask; + __gg__int128_to_field(a, + value, + 0, + truncation_e, + NULL); + break; + + case bit_clear_op: // set bits off + value &= ~bitmask; + __gg__int128_to_field(a, + value, + 0, + truncation_e, + NULL); + break; + + case bit_on_op: // true if any bitmask bit is on + retval = bitmask & value; + break; + + case bit_off_op: // true if any bitmask bit is off + retval = bitmask & ~value; + break; + + default: + __gg__abort("__gg__bitop() unknown operation code"); + break; + } + + return retval; + } + +extern "C" +void +__gg__bitwise_op( cblc_field_t *tgt, + cblc_field_t *a, + bitop_t op, + size_t bitmask) + { + int rdigits; + __int128 value = __gg__binary_value_from_field(&rdigits, a); + switch(op) + { + case bit_and_op: + value &= bitmask; + __gg__int128_to_field(tgt, + value, + 0, + truncation_e, + NULL); + break; + + case bit_or_op: + value |= bitmask; + __gg__int128_to_field(tgt, + value, + 0, + truncation_e, + NULL); + break; + + case bit_xor_op: + value ^= bitmask; + __gg__int128_to_field(tgt, + value, + 0, + truncation_e, + NULL); + break; + + default: + __gg__abort("__gg__bitwise_op() unknown operation code"); + break; + } + } + +extern "C" +void +__gg__set_initial_switch_value( ) + { + // We need to establish the initial value of the UPSI-1 switch register + // We are using IBM's conventions: + // https://www.ibm.com/docs/en/zvse/6.2?topic=SSB27H_6.2.0/fa2sf_communicate_appl_progs_via_job_control.html + // UPSI 10000110 means that bits 0, 5, and 6 are on, which means that SW-0, SW-5, and SW-6 are on. + + __int128 value = 0; + __int128 bit = 1; + char ach[129]; + memset(ach, 0, sizeof(ach)); + char *p = getenv("UPSI"); + if( p ) + { + snprintf(ach, sizeof(ach), "%s", p); + p = ach; + while(*p) + { + if( *p++ == ascii_1 ) + { + value |= bit; + } + bit <<= 1 ; + } + } + __gg__data_upsi_0[0] = (value>>0) & 0xFF; + __gg__data_upsi_0[1] = (value>>8) & 0xFF; + } + +static int +is_numeric_edited_numeric(cblc_field_t *, size_t, size_t ) + { + fprintf(stderr, "We don't know how to see if numeric-edited is numeric\n"); + abort(); + } + +static int +is_numeric_display_numeric(cblc_field_t *field, size_t offset, size_t size) + { + int retval = 1; + bool signable = !!(field->attr & signable_e); + bool leading = !!(field->attr & leading_e); + bool separate = !!(field->attr & separate_e); + + char *digits = (char *)(field->data + offset); + char *digits_e = digits + size; + + if( leading && separate && signable ) + { + // First character must be +/- + if( digits < digits_e + || ( *digits != internal_plus + && *digits != internal_minus) ) + { + retval = 0; + } + digits += 1; + } + + if( !leading && separate && signable ) + { + // Last character must be +/- + digits_e -= 1; + if( digits < digits_e + || ( *digits_e != internal_plus + && *digits_e != internal_minus) ) + { + retval = 0; + } + } + + if( leading && !separate && signable ) + { + // The first character is allowed to have a sign bit. + if( digits < digits_e ) + { + unsigned char first_char = (unsigned char)*digits; + turn_sign_bit_off(&first_char); + if(first_charinternal_9) + { + retval = 0; + } + } + digits += 1; + } + + if( !leading && !separate && signable ) + { + // The final character is allowed to have a sign bit. + if( digits < digits_e ) + { + digits_e -= 1; + unsigned char final_char = (unsigned char)*digits_e; + turn_sign_bit_off(&final_char); + if(final_charinternal_9) + { + retval = 0; + } + } + } + + // all remaining characters are supposed to be zero through nine + while( digits < digits_e ) + { + if( (unsigned char)(*digits)internal_9 ) + { + retval = 0; + break; + } + digits += 1; + } + return retval; + } + +static int +is_packed_numeric(cblc_field_t *field, size_t offset, size_t size) + { + int retval = 1; + bool is_comp6 = !!(field->attr&packed_no_sign_e); + int digits = field->digits; + bool signable = !!(field->attr & signable_e); + unsigned char *bytes = field->data + offset; + + int nybble = 0; + int nybble_e = nybble + digits; + unsigned char should_be_zero = 0; + if( is_comp6 ) + { + // This is packed decimal with no sign nybble at the end + if( digits & 1 ) + { + // There are an odd number of digits, so the string starts on the + // the right side of the first byte + nybble += 1; + nybble_e += 1; + should_be_zero = *bytes & 0xF0; + } + } + else + { + // This is packed decimal, and ends with a sign nybble + if( size ) + { + unsigned char nyb = bytes[size-1] & 0x0F; + if( !signable && nyb != 0x0F) + { + retval = 0; + } + if( signable && nyb != 0x0C && nyb != 0x0D ) + { + retval = 0; + } + } + if( !(digits & 1) ) + { + // There are an even number of digits before the sign nybble. So the + // string starts on the right side of the first byte + nybble += 1; + nybble_e += 1; + should_be_zero = *bytes & 0xF0; + } + } + if( should_be_zero != 0 ) + { + retval = 0; + } + // At this point, all nybbles between nybble and nybble_e should be between + // 0x00 and 0x09. + while(nybble < nybble_e) + { + unsigned char nyb = bytes[nybble/2]; + if( !(nybble & 1)) + { + nyb >>= 4; + } + else + { + nyb &= 0xF; + } + if( nyb > 0x09 ) + { + retval = 0; + break; + } + nybble += 1; + } + return retval; + } + +static int +is_alpha_a_number(cblc_field_t *field, size_t offset, size_t size) + { + int retval = 1; + unsigned char *bytes = (field->data + offset); + for( size_t i=0; i internal_9) ) + { + retval = 0; + break; + } + } + return retval; + } + +extern "C" +int +__gg__classify( classify_t type, + cblc_field_t *field, + size_t offset, + size_t size) + { + // The default answer is TRUE + int retval = 1; + + const unsigned char *alpha = (unsigned char *)(field->data+offset); + + size_t str_length = size; + + const unsigned char *omega = alpha + str_length; + + if(alpha >= omega) + { + // If there is nothing there, then it can't be TRUE. Can it? + retval = 0; + } + + unsigned char ch; + switch(type) + { + case ClassNumericType: + { + switch( field->type ) + { + case FldNumericEdited: + retval = is_numeric_edited_numeric(field, offset, size); + break; + case FldNumericDisplay: + retval = is_numeric_display_numeric(field, offset, size); + break; + case FldPacked: + retval = is_packed_numeric(field, offset, size); + break; + case FldGroup: + case FldAlphanumeric: + case FldAlphaEdited: + retval = is_alpha_a_number(field, offset, size); + break; + + case FldNumericBinary: + case FldNumericBin5: + // These need to checked for fitting into field->digits + break; + + default: + fprintf(stderr, + "We need code for %s numeric type %d\n", + field->name, + field->type); + abort(); + break; + } + + break; + } + + case ClassAlphabeticType: + while(alpha < omega) + { + ch = (*alpha++)&0xFF; + if( ch == internal_space ) + { + continue; + } + // If necessary, this could be sped up with the creation of + // appropriate mapping tables. + + // The oddball construction of this if() statement is a consequence of + // EBCDIC. Because of peculiarities going all the back to the encoding + // of characters on IBM cards, where it wasn't a good idea to have too + // many consecutive punches in a column because it would weaken the card + // to the point where its structural integrity might be threatened, the + // coding for the letter of the alphabet are not contiguous. + if(!( ( ch >= internal_A && ch <= internal_I) + || (ch >= internal_J && ch <= internal_R) + || (ch >= internal_S && ch <= internal_Z) + || (ch >= internal_a && ch <= internal_i) + || (ch >= internal_j && ch <= internal_r) + || (ch >= internal_s && ch <= internal_z) ) ) + { + // The character is not alphabetic + retval = 0; + break; + } + } + break; + + case ClassLowerType: + while(alpha < omega) + { + ch = *alpha++; + if( ch == internal_space ) + { + continue; + } + if(!( ( ch >= internal_a && ch <= internal_i) + || (ch >= internal_j && ch <= internal_r) + || (ch >= internal_s && ch <= internal_z) ) ) + { + retval = 0; + break; + } + } + break; + case ClassUpperType: + while(alpha < omega) + { + ch = *alpha++; + if( ch == internal_space ) + { + continue; + } + if(!( ( ch >= internal_A && ch <= internal_I) + || (ch >= internal_J && ch <= internal_R) + || (ch >= internal_S && ch <= internal_Z) ) ) + { + retval = 0; + break; + } + } + break; + + case ClassInvalidType: + case ClassDbcsType: + case ClassKanjiType: + default: + warnx("%s(): Don't know how to handle %s", + __func__, + classify_str(type)); + abort(); + break; + } + + return retval; + } + +extern "C" +int +__gg__accept_envar( cblc_field_t *tgt, + size_t tgt_offset, + size_t tgt_length, + cblc_field_t *name, + size_t name_offset, + size_t name_length) + { + int retval; + tgt_length = tgt_length ? tgt_length : tgt->capacity; + name_length = name_length ? name_length : name->capacity; + + // Pick up the environment variable name, which is in teh internal codeset + static char *env = NULL; + static size_t env_length = 0; + if( env_length < name_length+1 ) + { + env_length = name_length+1; + env = (char *)realloc(env, env_length); + } + memcpy(env, name->data + name_offset, name_length); + env[name_length] = '\0'; + + // Get rid of leading and trailing internal_space characters: + char *trimmed_env = brute_force_trim(env); + + // Convert the name to the console codeset: + __gg__internal_to_console_in_place(trimmed_env, strlen(trimmed_env)); + + // Pick up the environment variable, and convert it to the internal codeset + char *p = getenv(trimmed_env); + if(p) + { + char *pp = strdup(p); + console_to_internal(pp, strlen(pp)); + retval = 0; // Okay + move_string(tgt, tgt_offset, tgt_length, pp); + free(pp); + } + else + { + retval = 1; // Could't find it + exception_raise(ec_argument_imp_environment_e); + } + + return retval; + } + +extern "C" +bool +__gg__set_envar(cblc_field_t *name, + size_t name_offset, + size_t name_length, + cblc_field_t *value, + size_t value_offset, + size_t value_length) + { + bool retval = false; // true means the variable existed: + + name_length = name_length ? name_length : name->capacity; + value_length = value_length ? value_length : value->capacity; + + static char *env = NULL; + static size_t env_length = 0; + static char *val = NULL; + static size_t val_length = 0; + if( env_length < name_length+1 ) + { + env_length = name_length+1; + env = (char *)realloc(env, env_length); + } + if( val_length < value_length+1 ) + { + val_length = value_length+1; + val = (char *)realloc(val, val_length); + } + + // The name and the value arrive in the internal codeset: + memcpy(env, name->data+name_offset , name_length); + env[name_length] = '\0'; + memcpy(val, value->data+value_offset, value_length); + val[value_length] = '\0'; + + // Get rid of leading and trailing internal_space characters + char *trimmed_env = brute_force_trim(env); + char *trimmed_val = brute_force_trim(val); + + // Conver them to the console codeset + __gg__internal_to_console_in_place(trimmed_env, strlen(trimmed_env)); + __gg__internal_to_console_in_place(trimmed_val, strlen(trimmed_val)); + + if( getenv(trimmed_env) ) + { + // It already existed: + retval = true; + } + + // And now, anticlimactically, set the variable: + setenv(trimmed_env, trimmed_val, 1); + + return retval; + } + +static int stashed_argc = 0; +static char **stashed_argv = NULL; + +extern "C" +void +__gg__stash_argc_argv(int argc, char **argv) + { + stashed_argc = argc; + stashed_argv = argv; + + // This routine is called once by main(), so it is a convenient place to make + // the stack much bigger, because when people create COBOL programs with + // ridiculous numbers of variables, the stack gets ridiculously large. + + struct rlimit stack_size = {33554432, 33554432}; + if( setrlimit(RLIMIT_STACK, &stack_size) ) + { + fprintf(stderr, "warning: attempt to set stack size to 32M failed\n"); + } + } + +static void +command_line_plan_b() + { + // It's vaguely possible that somebody can try to access these command-line + // functions without a main() function having been invoked. This code, for + // example, could have been created as a stand-alone .so, or it could be + // from a COBOL .o that was linked to main() from another language. So, we + // are going to believe that /proc/cmdline is available, and proceed from + // there: + if( !stashed_argc ) + { + static char input[4096]; + sprintf(input, "/proc/%ld/cmdline", (long)getpid()); + FILE *f = fopen(input, "r"); + if( f ) + { + size_t bytes_read = fread(input, 1, sizeof(input), f); + fclose(f); + if( bytes_read ) + { + char *p = input; + char *p_end = p + bytes_read; + char prior_char = '\0'; + while( p < p_end ) + { + if( prior_char == '\0' ) + { + stashed_argc += 1; + stashed_argv = (char **)realloc(stashed_argv, + stashed_argc * sizeof(char *)); + stashed_argv[stashed_argc-1] = p; + } + prior_char = *p++; + } + } + } + } + } + +extern "C" +void +__gg__get_argc(cblc_field_t *dest, size_t offset, size_t length) + { + command_line_plan_b(); + char ach[128]; + sprintf(ach, "%d", stashed_argc); + ascii_to_internal_str(ach, strlen(ach)); + move_string(dest, offset, length, ach); + } + +extern "C" +int +__gg__get_argv( cblc_field_t *dest, + size_t dest_offset, + size_t dest_length, + cblc_field_t *index, + size_t index_offset, + size_t index_size) + { + int retcode; + command_line_plan_b(); + int rdigits; + __int128 N = get_binary_value_local(&rdigits, + index, + index->data + index_offset, + index_size); + + // N is 1-based, per normal COBOL. We have to decrement it here: + N -= 1; + + dest_length = dest_length ? dest_length : dest->capacity; + + // If he gives us fractional digits, just truncate + N /= __gg__power_of_ten(rdigits); + + if( N >= stashed_argc || N < 0 ) + { + exception_raise(ec_argument_imp_command_e); + retcode = 1; // Error + } + else + { + char *retval = strdup(stashed_argv[N]); + console_to_internal(retval, strlen(retval)); + move_string(dest, dest_offset, dest_length, retval); + free(retval); + retcode = 0; // Okay + } + return retcode; + } + +extern "C" +int +__gg__get_command_line( cblc_field_t *field, + size_t offset, + size_t flength) + { + int retcode; + command_line_plan_b(); + size_t length = 1; + char *retval = (char *)malloc(length); + *retval = NULLCH; + + for( int i=1; i length ) + { + length *= 2; + retval = (char *)realloc(retval, length); + } + if( *retval ) + { + strcat(retval, " "); + } + strcat(retval, stashed_argv[i]); + } + + if( *retval ) + { + flength = flength ? flength : field->capacity; + console_to_internal(retval, strlen(retval)); + move_string(field, offset, flength, retval); + retcode = 0; // Okay + } + else + { + exception_raise(ec_argument_imp_command_e); + retcode = 1;// Error + } + + free(retval); + return retcode; + } + +extern "C" +void +__gg__set_pointer(cblc_field_t *target, + size_t target_o, + int target_flags, + cblc_field_t *source, + size_t source_o, + int source_flags) + { + void *source_address; + if( source_flags & REFER_T_ADDRESS_OF ) + { + // This is SET TO ADDRESS OF SOURCE + source_address = source->data + source_o; + } + else + { + // This is SET TO POINTER + if( source ) + { + source_address = *(void **)(source->data + source_o); + } + else + { + // This is SET xxx TO NULL + source_address = NULL; + } + } + + if( target_flags & REFER_T_ADDRESS_OF ) + { + // This is SET ADDRESS OF target TO .... + // We know it has to be an unqualified LINKAGE level 01 or level 77 + target->data = (unsigned char *)source_address; + // The caller will propogate data + offset to their children. + } + else + { + // This is SET TO .... + if( source->type == FldLiteralN ) + { + // This is [almost certainly] INITIALIZE when -fdefaultbyte + // was specified. + memset( target->data+target_o, + *(unsigned char *)source_address, + target->capacity); + } + else + { + *(void **)(target->data+target_o) = source_address; + } + } + } + +extern "C" +void +__gg__alphabet_use( cbl_encoding_t encoding, + size_t alphabet_index) + { + // We simply replace the values in the current program_state. If the + // state needs to be saved -- for example, if we are doing a SORT with an + // ALPHABET override -- that's up to the caller + + // When there is no DATA DIVISION, program_states can be empty when + // we arrive here. + if( program_states.empty() ) + { + initialize_program_state(); + } + + switch( encoding ) + { + case ASCII_e: + case iso646_e: + __gg__low_value_character = DEGENERATE_LOW_VALUE; + __gg__high_value_character = DEGENERATE_HIGH_VALUE; + + program_states.back().rt_low_value_character = DEGENERATE_LOW_VALUE; + program_states.back().rt_high_value_character = DEGENERATE_HIGH_VALUE; + + if( !internal_is_ebcdic ) + { + program_states.back().rt_collation = __gg__one_to_one_values; + } + else + { + program_states.back().rt_collation = __gg__ebcdic_to_cp1252_collation; + } + + break; + + case EBCDIC_e: + __gg__low_value_character = DEGENERATE_LOW_VALUE; + __gg__high_value_character = DEGENERATE_HIGH_VALUE; + + program_states.back().rt_low_value_character = DEGENERATE_LOW_VALUE; + program_states.back().rt_high_value_character = DEGENERATE_HIGH_VALUE; + if( internal_is_ebcdic ) + { + program_states.back().rt_collation = __gg__one_to_one_values; + } + else + { + program_states.back().rt_collation = __gg__cp1252_to_ebcdic_collation; + } + break; + + case custom_encoding_e: + { + std::unordered_map::const_iterator it = + __gg__alphabet_states.find(alphabet_index); + + if( it == __gg__alphabet_states.end() ) + { + __gg__abort("__gg__alphabet_use() fell off the end of __gg__alphabet_states"); + } + __gg__low_value_character = it->second.low_char; + __gg__high_value_character = it->second.high_char; + program_states.back().rt_low_value_character = it->second.low_char; + program_states.back().rt_high_value_character = it->second.high_char; + + program_states.back().rt_collation = it->second.collation; + break; + } + } + return; + } + +extern "C" +void +__gg__ascii_to_internal_field(cblc_field_t *var) + { + ascii_to_internal_str((char *)var->data, var->capacity); + } + +extern "C" +void +__gg__ascii_to_internal(char *location, size_t length) + { + ascii_to_internal_str(location, length); + } + +extern "C" +void +__gg__console_to_internal(char *location, size_t length) + { + console_to_internal(location, length); + } + +extern "C" +void +__gg__parser_set_conditional(cblc_field_t *var, int figconst_) + { + cbl_figconst_t figconst = (cbl_figconst_t)figconst_; + + unsigned char special = internal_space; + switch(figconst) + { + case space_value_e: + special = *__gg__data_space; + break; + case low_value_e: + special = *__gg__data_low_values; + break; + case high_value_e: + special = *__gg__data_high_values; + break; + case zero_value_e: + special = *__gg__data_zeros; + break; + case quote_value_e: + special = *__gg__data_quotes; + break; + default: + break; + } + memset( var->data, special, var->capacity); + } + +extern "C" +void +__gg__internal_to_console_in_place(char *loc, size_t length) + { + static size_t dest_size = MINIMUM_ALLOCATION_SIZE; + static char *dest = (char *)malloc(dest_size); + + internal_to_console(&dest, &dest_size, loc, length); + memcpy(loc, dest, length); + } + +extern "C" +int +__gg__routine_to_call(char *name, + int program_id) + { + // The list of names is sorted, so at the very least this should be replaced + // with a binary search: + + std::unordered_map::const_iterator it = + accessible_programs.find(program_id); + + if(it == accessible_programs.end()) + { + __gg__abort("__gg__routine_to_call() couldn't find program_id"); + } + + char **names = *(it->second); + + int retval = -1; + int i=0; + + if( names ) + { + while(*names) + { + if( strstr(*names, name) ) + { + // The first part of the names match + if( (*names)[strlen(name)] == '.' ) + { + // And the first character after the match is a '.' + retval = i; + break; + } + } + i += 1; + names += 1; + } + } + return retval; + } + +extern "C" +__int128 +__gg__fetch_call_by_value_value(cblc_field_t *field, + size_t field_o, + size_t field_s) + + { + int rdigits; + unsigned char *data = field->data + field_o; + size_t length = field_s; + + __int128 retval = 0; + switch(field->type) + { + case FldGroup: + case FldAlphanumeric: + case FldAlphaEdited: + case FldLiteralA: + retval = *(char *)data; + break; + + case FldFloat: + { + switch(length) + { + case 4: + *(float *)(&retval) = *(float *)data; + break; + + case 8: + *(double *)(&retval) = *(double *)data; + break; + + case 16: + // *(_Float128 *)(&retval) = double(*(_Float128 *)data); + _Float128 t; + memcpy(&t, data, 16); + memcpy(&retval, &t, 16); + break; + } + break; + } + + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldNumericDisplay: + case FldNumericEdited: + case FldLiteralN: + case FldIndex: + case FldPointer: + retval = __gg__binary_value_from_qualified_field( &rdigits, + field, + field_o, + field_s); + if( rdigits ) + { + retval /= __gg__power_of_ten(rdigits); + } + default: + break; + } + return retval; + } + +extern "C" +void +__gg__assign_value_from_stack(cblc_field_t *dest, __int128 parameter) + { + switch(dest->type) + { + case FldGroup: + case FldAlphanumeric: + case FldAlphaEdited: + case FldNumericEdited: + if( dest->capacity >= 1) + { + warnx("%s is not valid for BY VALUE", dest->name); + abort(); + } + break; + + case FldFloat: + { + switch(dest->capacity) + { + case 4: + *(float *)(dest->data) = *(float *)¶meter; + break; + + case 8: + *(double *)(dest->data) = *(double *)¶meter; + break; + + case 16: + // *(_Float128 *)(dest->data) = *(_Float128 *)¶meter; + _Float128 t; + memcpy(&t, ¶meter, 16); + memcpy(dest->data, &t, 16); + break; + } + break; + } + + case FldNumericBinary: + case FldPacked: + case FldNumericBin5: + case FldNumericDisplay: + case FldLiteralN: + case FldIndex: + case FldPointer: + __gg__int128_to_field(dest, + parameter, + 0, + truncation_e, + NULL); + break; + + default: + break; + } + } + +extern "C" +int +__gg__literaln_alpha_compare(char *left_side, + cblc_field_t *right, + size_t offset, + size_t length, + int flags) + { + int retval; + if( length == 0 ) + { + length = right->capacity; + } + retval = compare_strings( (char *)left_side, + strlen(left_side), + false, + (char *)right->data + offset, + length, + !!(flags & REFER_T_MOVE_ALL) ); + return retval; + } + +static char * +string_in(char *str, char *str_e, char *frag, char *frag_e) + { + // This simple routine could be improved. Instead of using memcmp, we could + // use established, albeit complex, techniques of string searching: + + // Looking for "abcde" in "abcdabcde", for example. One could notice that + // starting at the first 'a' results in a mismatch at the second 'a'. There + // is thus no need to start the second search at the first 'b' in the searched + // string; one could jump ahead to the second 'a' and continue from there. + + // Feel free. It won't matter in the real world; a program whose innermost + // loop is an UNSTRING is difficult to imagine. But feel free. + + char *retval = NULL; + size_t nchars = frag_e - frag; + char *p = str; + while( p + nchars <= str_e ) + { + if( memcmp(p, frag, nchars) == 0 ) + { + retval = p; + break; + } + p += 1; + } + return retval; + } + +extern "C" +int +__gg__unstring( cblc_field_t *id1, // The string being unstring + size_t id1_o, + size_t id1_s, + size_t ndelimiteds, // The number of DELIMITED entries + char *all_flags, // The number of ALL flags, one per ndelimiteds + size_t nreceivers, // The number of DELIMITER receivers + cblc_field_t *id7, // The index of characters, both for starting updated at end + size_t id7_o, + size_t id7_s, + cblc_field_t *id8, // Count of the number of times identifier-4 was updated + size_t id8_o, + size_t id8_s) + { + // The names of the parameters are based on the ISO 1989:2014 specification. + + // There are complexities because of figurative constants, including the + // LOW-VALUE figurative constant, which precludes the use of string + // operations that would be confused by embedded NUL characters. Dammit. + + // For each delimiter, there is an identifier-4 receiver that must be + // resolved. Each might have an identifier-5 delimiter, and each might have + // an identifier-6 count. + + cblc_field_t **id2 = __gg__treeplet_1f; // The delimiting strings; one per ndelimiteds + size_t *id2_o = __gg__treeplet_1o; + size_t *id2_s = __gg__treeplet_1s; + cblc_field_t **id4 = __gg__treeplet_2f; // The delimited string; one per nreceiver + size_t *id4_o = __gg__treeplet_2o; + size_t *id4_s = __gg__treeplet_2s; + cblc_field_t **id5 = __gg__treeplet_3f; // The delimiting string; one per receiver + size_t *id5_o = __gg__treeplet_3o; + size_t *id5_s = __gg__treeplet_3s; + cblc_field_t **id6 = __gg__treeplet_4f; // The count of characters examined; one per receiver + size_t *id6_o = __gg__treeplet_4o; + size_t *id6_s = __gg__treeplet_4s; + + // Initialize the state variables + int overflow = 0; + int tally = 0; + int pointer = 1; + size_t nreceiver; + char *left = NULL; + char *right = NULL; + int previous_delimiter; + + if( id8 ) + { + int rdigits; + tally = (int)__gg__binary_value_from_qualified_field(&rdigits, + id8, + id8_o, + id8_s); + } + + if( id7 ) + { + int rdigits; + pointer = (int)__gg__binary_value_from_qualified_field(&rdigits, + id7, + id7_o, + id7_s); + } + + // As per the spec, if the string is zero-length; we are done. + if( id1_s == 0 ) + { + goto done; + } + + // As per the spec, we have an overflow condition if pointer is out of + // range: + if( pointer < 1 || pointer > (int)id1_s ) + { + overflow = 1; + goto done; + } + + left = (char *)(id1->data+id1_o) + pointer-1; + right = (char *)(id1->data+id1_o) + id1_s; + + if( ndelimiteds == 0 ) + { + // There are no DELIMITED BY identifier-2 values, so we just peel off + // characters from identifier-1 and put them into each identifier-4: + for( size_t i=0; i= right ) + { + break; + } + size_t id_4_size = id4_s[i]; + if( id4[i]->attr & separate_e ) + { + // The receiver is NumericDisplay with a separate signe + id_4_size = id4_s[i] - 1; + } + + // Make sure id_4_size doesn't move past the end of the universe + if( left + id_4_size > right ) + { + id_4_size = right - left; + } + + // Move the data into place: + move_string(id4[i], id4_o[i], id4_s[i], left, id_4_size); + + // Update the state variables: + left += id_4_size; + pointer += id_4_size; + tally += 1; + } + goto done; + } + + // Arriving here means there is some number of ndelimiteds + + nreceiver = 0; + previous_delimiter = -1; + while( left < right ) + { + // Starting at 'left', see if we can find any of the delimiters + char *leftmost_delimiter = NULL; + int ifound = -1; + cbl_figconst_t figconst; + char achfigconst[1]; + for( size_t i=0; iattr & FIGCONST_MASK); + + switch(figconst) + { + case low_value_e : + achfigconst[0] = ascii_to_internal(__gg__low_value_character); + pfound = string_in( left, + right, + achfigconst, + achfigconst+1); + break; + + case zero_value_e : + achfigconst[0] = internal_zero; + pfound = string_in( left, + right, + achfigconst, + achfigconst+1); + break; + + case space_value_e : + achfigconst[0] = internal_space; + pfound = string_in( left, + right, + achfigconst, + achfigconst+1); + break; + + case quote_value_e : + achfigconst[0] = ascii_to_internal(__gg__quote_character); + pfound = string_in( left, + right, + achfigconst, + achfigconst+1); + break; + + case high_value_e : + achfigconst[0] = ascii_to_internal(__gg__high_value_character); + pfound = string_in( left, + right, + achfigconst, + achfigconst+1); + break; + + case normal_value_e : + default: + pfound = string_in( left, + right, + (char *)(id2[i]->data+id2_o[i]), + (char *)(id2[i]->data+id2_o[i]) + id2_s[i]); + break; + } + + if( pfound ) + { + // We found a delimiter + if( !leftmost_delimiter || pfound < leftmost_delimiter ) + { + ifound = i; + leftmost_delimiter = pfound; + } + } + } + + if( ifound >= 0 + && leftmost_delimiter == left + && ifound == previous_delimiter ) + { + // We found another instance of an ALL delimiter. + // So, we just skip it. + left += id2_s[previous_delimiter]; + pointer += id2_s[previous_delimiter]; + continue; + } + + // We did not re-find an ALL DELIMITER + previous_delimiter = -1; + + // If we've used up all receivers, we bail at this point + if( nreceiver >= nreceivers ) + { + break; + } + + if( ifound >= 0 && all_flags[ifound] == ascii_1 ) + { + // Arriving here means we found a new delimiter. + // If the ALL flag was on, set up to notice repeats + previous_delimiter = ifound; + } + + if( !leftmost_delimiter ) + { + // We were unable to find a delimiter, so we eat up the remainder + // of the sender: + leftmost_delimiter = right; + } + + // Apply what we have learned to the next receiver: + + size_t examined = leftmost_delimiter - left; + + // Move the data into place: + move_string(id4[nreceiver], id4_o[nreceiver], id4_s[nreceiver], left, examined); + + // Update the left pointer + left = leftmost_delimiter; + if( ifound >= 0 ) + { + // And skip over the delimiter + left += id2_s[ifound]; + } + + if( id5[nreceiver] ) + { + if( ifound >= 0 ) + { + if( figconst ) + { + move_string(id5[nreceiver], id5_o[nreceiver], id5_s[nreceiver], + achfigconst, + 1); + } + else + { + move_string(id5[nreceiver], id5_o[nreceiver], id5_s[nreceiver], + (char *)(id2[ifound]->data+id2_o[ifound]), + id2_s[ifound]); + } + } + else + { + move_string(id5[nreceiver], id5_o[nreceiver], id5_s[nreceiver], ""); + } + } + + if( id6[nreceiver] ) + { + __gg__int128_to_qualified_field(id6[nreceiver], + id6_o[nreceiver], + id6_s[nreceiver], + (__int128)examined, + 0, + truncation_e, + NULL ); + } + + // Update the state variables: + pointer += examined + id2_s[ifound]; + tally += 1; + nreceiver += 1; + } + +done: + + if( id8 ) + { + __gg__int128_to_qualified_field(id8, + id8_o, + id8_s, + (__int128)tally, + 0, + truncation_e, + NULL ); + } + + if( id7 ) + { + __gg__int128_to_qualified_field(id7, + id7_o, + id7_s, + (__int128)pointer, + 0, + truncation_e, + NULL ); + } + + if( left < right ) + { + overflow = 1; + } + + return overflow; + } + +static std::set to_be_canceled; + +extern "C" +void __gg__to_be_canceled(size_t function_pointer) + { + if( function_pointer ) + { + to_be_canceled.insert(function_pointer); + } + } + +extern "C" +int __gg__is_canceled(size_t function_pointer) + { + int retval = 0; + std::set::iterator it = to_be_canceled.find(function_pointer); + if( it == to_be_canceled.end() ) + { + retval = 0; + } + else + { + retval = 1; + to_be_canceled.erase(it); + } + return retval; + } + +// Tue Feb 28 10:10:16 2023 +// Associate specific I/O status an with exception condition. +// Cf. ISO Table 14 — Exception-names and exception conditions + +static inline ec_type_t +local_ec_type_of( file_status_t status ) + { + ec_type_t retval; + int status10 = (int)status / 10; + if( !(status10 < 10 && status10 >= 0) ) + { + __gg__abort("local_ec_type_of(): status10 out of range"); + } + switch(status10) + { + case 0: + // This actually should be ec_io_warning_e, but that's new for ISO 1989:2013 + retval = ec_none_e; + break; + case 1: + retval = ec_io_at_end_e; + break; + case 2: + retval = ec_io_invalid_key_e; + break; + case 3: + retval = ec_io_permanent_error_e; + break; + case 4: + retval = ec_io_logic_error_e; + break; + case 5: + retval = ec_io_record_operation_e; + break; + case 6: + retval = ec_io_file_sharing_e; + break; + case 7: + retval = ec_io_record_content_e; + break; + case 9: + retval = ec_io_imp_e; + break; + + default: + retval = ec_none_e; + break; + } + return retval; + } + +bool +cbl_enabled_exceptions_array_t::match( ec_type_t ec, size_t file ) const { + auto output = enabled_exception_match( ecs, ecs + nec, ec, file ); + return output < ecs + nec? output->enabled : false; +} + +static cbl_enabled_exceptions_array_t enabled_ECs; + +/* + * Store and report the enabled exceptions. + * 7.3.20.3 General rules: + * 1) The default TURN directive is '>>TURN EC-ALL CHECKING OFF'. + */ +struct exception_descr_t { + bool location; + std::set files; +}; + +/* + * Compare the raised exception, cbl_exception_t, to the USE critera + * of a declarative, cbl_declarative_t. Return FALSE if the exception + * raised was already handled by the statement that provoked the + * exception, as indicated by the "handled" file status. + * + * This copes with I/O exceptions: ec_io_e and friends. + */ + +class match_file_declarative { + const cbl_exception_t& oops; + const ec_type_t handled_type; + protected: + bool handled() const { + return oops.type == handled_type || oops.type == ec_none_e; + } + public: + match_file_declarative( const cbl_exception_t& oops, file_status_t handled ) + : oops(oops), handled_type( local_ec_type_of(handled) ) + {} + + bool operator()( const cbl_declarative_t& dcl ) { + + if( getenv("match_declarative") && oops.type) { + warnx("match_file_declarative: checking: oops %s dcl %s (handled %s) ", + local_ec_type_str(oops.type), + local_ec_type_str(dcl.type), + local_ec_type_str(handled_type)); + } + + // Declarative is for the raised exception and not handled by the statement. + if( handled() ) return false; + bool matches = enabled_ECs.match(dcl.type); + + // I/O declaratives match by file or mode, not EC. + if( dcl.is_format_1() ) { // declarative is for particular files or mode + if( dcl.nfile > 0 ) { + matches = dcl.match_file(oops.file); + } else { + matches = oops.mode == dcl.mode; + } + } + + if( matches && getenv("match_declarative") ) { + warnx(" matches exception %s (file %zu mode %s)", + local_ec_type_str(oops.type), + oops.file, + cbl_file_mode_str(oops.mode)); + } + + return matches; + } +}; + +cblc_file_t * __gg__file_stashed(); +static ec_type_t ec_raised_and_handled; + +static void +default_exception_handler( ec_type_t ec) +{ + if( ec != ec_none_e ) { + auto p = std::find_if( __gg__exception_table, __gg__exception_table_end, + [ec](const ec_descr_t& descr) { + return descr.type == ec; + } ); + if( p == __gg__exception_table_end ) { + err(EXIT_FAILURE, + "logic error: %s:%zu: %s unknown exception %x", + ec_status.source_file, + ec_status.lineno, + ec_status.statement, + ec ); + } + + const char *disposition = NULL; + + switch( p->disposition ) { + case ec_category_fatal_e: + warnx("fatal exception at %s:%zu:%s %s (%s)", + ec_status.source_file, + ec_status.lineno, + ec_status.statement, + p->name, + p->description ); + abort(); + break; + case ec_category_none_e: + disposition = "category none?"; + break; + case ec_category_nonfatal_e: + disposition = "nonfatal"; + break; + case ec_category_implementor_e: + disposition = "implementor"; + break; + case uc_category_none_e: + disposition = "uc_category_none_e"; + break; + case uc_category_fatal_e: + disposition = "uc_category_fatal_e"; + break; + case uc_category_nonfatal_e: + disposition = "uc_category_nonfatal_e"; + break; + case uc_category_implementor_e: + disposition = "uc_category_implementor_e"; + break; + } + + // If the EC was handled by a declarative, keep mum. + if( ec == ec_raised_and_handled ) { + ec_raised_and_handled = ec_none_e; + return; + } + + warnx("%s exception at %s:%zu:%s %s (%s)", + disposition, + ec_status.source_file, + ec_status.lineno, + ec_status.statement, + p->name, + p->description ); + } +} + +extern "C" +void +__gg__check_fatal_exception() +{ + if( ec_raised_and_handled == ec_none_e ) return; + /* + * "... if checking for EC-I-O exception conditions is not enabled, + * there is no link between EC-I-O exception conditions and I-O + * status values." + */ + if( ec_cmp(ec_raised_and_handled, ec_io_e) ) return; + + default_exception_handler(ec_raised_and_handled); + ec_raised_and_handled = ec_none_e; +} + +extern "C" +void +__gg__clear_exception() +{ + ec_raised_and_handled = ec_none_e; +} + + +cbl_enabled_exceptions_array_t& +cbl_enabled_exceptions_array_t::operator=( const cbl_enabled_exceptions_array_t& input ) +{ + if( nec == input.nec ) { + if( nec == 0 || 0 == memcmp(ecs, input.ecs, nbytes()) ) return *this; + } + + if( nec < input.nec ) { + if( nec > 0 ) delete[] ecs; + ecs = new cbl_enabled_exception_t[1 + input.nec]; + } + if( input.nec > 0 ) { + auto pend = std::copy( input.ecs, input.ecs + input.nec, ecs ); + std::fill(pend, ecs + input.nec, cbl_enabled_exception_t()); + } + nec = input.nec; + return *this; +} + +// Update the list of compiler-maintained enabled exceptions. +extern "C" +void +__gg__stash_exceptions( size_t nec, cbl_enabled_exception_t *ecs ) +{ + enabled_ECs = cbl_enabled_exceptions_array_t(nec, ecs); + + if( false && getenv("match_declarative") ) + warnx("%s: %zu exceptions enabled", __func__, nec); +} + + +/* + * Match the raised exception against a declarative handler + * + * ECs unrelated to I/O are not matched to a Declarative unless + * enabled. Declaratives for I/O errors, on the other hand, match + * regardless of whether or not any EC is enabled. + * + * Declaratives handle I-O errors with USE Format 1. They don't name a + * specific EC. They're matched based on the file's status, + * irrespective of whether or not EC-I-O is enabled. If EC-I-O is + * enabled, and mentioned in a Declarative USE statement, then it is + * matched just like any other Format 3 USE statement. + */ +extern "C" +void +__gg__match_exception( cblc_field_t *index, + const cbl_declarative_t *dcls ) +{ + static const cbl_declarative_t no_declaratives[1] = {}; + + size_t ifile = __gg__exception_file_number; + // The exception file number is assumed to always be zero, unless it's + // been set to a non-zero value. Having picked up that value it is our job + // to immediately set it back to zero: + __gg__exception_file_number = 0; + + int handled = __gg__exception_handled; + cblc_file_t *stashed = __gg__file_stashed(); + + if( dcls == NULL ) dcls = no_declaratives; + size_t ndcl = dcls[0].section; + auto eodcls = dcls + 1 + ndcl, p = eodcls; + + auto ec = ec_status.update().unhandled(); + + // We need to set exception handled back to 0. We do it here because + // ec_status.update() looks at it + __gg__exception_handled = 0; + + if(__gg__exception_code != ec_none_e) // cleared by ec_status_t::update + { + __gg__abort("__gg__match_exception(): __gg__exception_code should be ec_none_e"); + } + if( ec == ec_none_e ) { + if( ifile == 0) goto set_exception_section; + + if( stashed == nullptr ) + { + __gg__abort("__gg__match_exception(): stashed is null"); + } + ec = local_ec_type_of( stashed->io_status ); + } + + if( ifile > 0 ) { // an I/O exception is raised + if( stashed == nullptr ) + { + __gg__abort("__gg__match_exception(): stashed is null (2)"); + } + auto mode = cbl_file_mode_t(stashed->mode_char); + cbl_exception_t oops = {0, ifile, ec, mode }; + p = std::find_if( dcls + 1, eodcls, + match_file_declarative(oops, file_status_t(handled)) ); + + } else { // non-I/O exception + auto enabled = enabled_ECs.match(ec); + if( enabled ) { + p = std::find_if( dcls + 1, eodcls, [ec] (const cbl_declarative_t& dcl) { + if( ! enabled_ECs.match(dcl.type) ) return false; + if( ! ec_cmp(ec, dcl.type) ) return false; + + if( getenv("match_declarative") ) { + warnx("__gg__match_exception:%d: matched " + "%s against mask %s for section #%zu", + __LINE__, + local_ec_type_str(ec), local_ec_type_str(dcl.type), + dcl.section); + } + return true; + } ); + if( p == eodcls ) { + default_exception_handler(ec); + } + } else { // not enabled + if( getenv("match_declarative") ) { + warnx("__gg__match_exception:%d: raised exception " + "%s is disabled (%zu enabled)", __LINE__, + local_ec_type_str(ec), enabled_ECs.nec); + } + } + } + + set_exception_section: + size_t retval = p == eodcls? 0 : p->section; + ec_raised_and_handled = retval? ec : ec_none_e; + + // If a declarative matches the raised exception, return its + // symbol_table index. + __gg__int128_to_field(index, + (__int128)retval, + 0, + truncation_e, + NULL); +} + +static std::vectorproc_signatures; +static std::vectorreturn_addresses; +static std::vectorbookmarks; + +extern "C" +void +__gg__pseudo_return_push( void *proc_signature, + void *return_address) + { + proc_signatures.push_back(proc_signature); + return_addresses.push_back(return_address); + __gg__exit_address = proc_signature; + } + +extern "C" +void * +__gg__pseudo_return_pop() + { + void *retval = return_addresses.back(); + + return_addresses.pop_back(); + proc_signatures.pop_back(); + + if( proc_signatures.size() > bookmarks.back() ) + { + __gg__exit_address = proc_signatures.back(); + } + else + { + // We can't go below the floor established by the bookmark. + __gg__exit_address = NULL; + } + + return retval; + } + +extern "C" +void +__gg__pseudo_return_bookmark() + { + bookmarks.push_back(proc_signatures.size()); + } + +extern "C" +void +__gg__pseudo_return_flush() + { + if( bookmarks.size() == 0 ) + { + __gg__abort("__gg__pseudo_return_flush(): bookmarks.size() is zero"); + } + proc_signatures.resize(bookmarks.back()); + return_addresses.resize(bookmarks.back()); + bookmarks.pop_back(); + + if( proc_signatures.size() ) + { + __gg__exit_address = proc_signatures.back(); + } + } + +extern "C" +_Float128 +__gg__float128_from_location(cblc_field_t *var, unsigned char *location) + { + _Float128 retval = 0; + switch( var->capacity ) + { + case 4: + { + retval = *(_Float32 *)location; + break; + } + + case 8: + { + retval = *(_Float64 *)location; + break; + } + + case 16: + { + //retval = *(_Float128 *)location; + memcpy(&retval, location, 16); + break; + } + } + return retval; + } + +extern "C" +__int128 +__gg__integer_from_float128(cblc_field_t *field) + { + _Float128 fvalue = __gg__float128_from_location(field, field->data); + // we round() to take care of the possible 2.99999999999... problem. + fvalue = roundf128(fvalue); + return (__int128)fvalue; + } + + +extern "C" +void +__gg__adjust_dest_size(cblc_field_t *dest, size_t ncount) + { + if( dest->attr & (intermediate_e) ) + { + if( dest->allocated < ncount ) + { + dest->allocated = ncount; + dest->data = (unsigned char *)realloc(dest->data, ncount); + } + dest->capacity = ncount; + } + } + +extern "C" +void +__gg__func_exception_location(cblc_field_t *dest) + { + char ach[512] = " "; + if( stashed_exception_code ) + { + ach[0] = '\0'; + if( stashed_exception_program_id ) + { + strcat(ach, stashed_exception_program_id); + strcat(ach, "; "); + } + + if( stashed_exception_paragraph ) + { + strcat(ach, stashed_exception_paragraph ); + if( stashed_exception_section ) + { + strcat(ach, " OF "); + strcat(ach, stashed_exception_section); + } + } + else + { + if( stashed_exception_section ) + { + strcat(ach, stashed_exception_section); + } + } + strcat(ach, "; "); + + if( stashed_exception_source_file ) + { + char achSource[128] = ""; + snprintf( achSource, + sizeof(achSource), + "%s:%d ", + stashed_exception_source_file, + stashed_exception_line_number); + strcat(ach, achSource); + } + else + { + strcpy(ach, " "); + } + } + __gg__adjust_dest_size(dest, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } + +extern "C" +void +__gg__func_exception_statement(cblc_field_t *dest) + { + char ach[128] = " "; + if(stashed_exception_statement) + { + snprintf(ach, sizeof(ach), "%s", stashed_exception_statement); + ach[sizeof(ach)-1] = '\0'; + } + __gg__adjust_dest_size(dest, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } + +extern "C" +void +__gg__func_exception_status(cblc_field_t *dest) + { + char ach[128] = ""; + if(stashed_exception_code) + { + ec_descr_t *p = __gg__exception_table; + while(p < __gg__exception_table_end ) + { + if( p->type == (ec_type_t)stashed_exception_code ) + { + snprintf(ach, sizeof(ach), "%s", p->name); + break; + } + p += 1; + } + } + else + { + strcpy(ach, " "); + } + __gg__adjust_dest_size(dest, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } + +static cblc_file_t *recent_file = NULL; + +extern "C" +void +__gg__set_exception_file(cblc_file_t *file) + { + if( getenv("match_declarative") ) + { + warnx("%s: %s", __func__, file->name); + } + recent_file = file; + ec_type_t ec = local_ec_type_of( file->io_status ); + if( ec ) + { + exception_raise(ec); + } + } + + +extern "C" +void +__gg__func_exception_file(cblc_field_t *dest, cblc_file_t *file) + { + char ach[128]; + if( !file ) + { + // This is where we process FUNCTION EXCEPTION-FILE + if( !(stashed_exception_code & ec_io_e) || !recent_file) + { + // There is no EC-I-O exception code, so we return two spaces + strcpy(ach, "00"); + } + else + { + if( sv_from_raise_statement ) + { + strcpy(ach, " "); + } + else + { + snprintf(ach, sizeof(ach), "%2.2d%s", recent_file->io_status, recent_file->name); + } + } + } + else + { + // This is where we process FUNCTION EXCEPTION-FILE file->name + if( file->prior_op == file_op_none ) + { + // this file hasn't been accessed + strcpy(ach, " "); + } + else + { + snprintf(ach, sizeof(ach), "%2.2d%s", file->io_status, file->name); + } + } + + __gg__adjust_dest_size(dest, strlen(ach)); + memcpy(dest->data, ach, strlen(ach)); + } + +extern "C" +void +__gg__set_exception_code(ec_type_t ec, int from_raise_statement) + { + if( getenv("match_declarative") ) + { + warnx("%s: raised %02x", __func__, ec); + } + sv_from_raise_statement = from_raise_statement; + + __gg__exception_code = ec; + if( ec == ec_none_e) + { + stashed_exception_code = 0 ; + stashed_exception_handled = 0 ; + stashed_exception_file_number = 0 ; + stashed_exception_file_status = 0 ; + stashed_exception_file_name = NULL ; + stashed_exception_program_id = NULL ; + stashed_exception_section = NULL ; + stashed_exception_paragraph = NULL ; + stashed_exception_source_file = NULL ; + stashed_exception_line_number = 0 ; + stashed_exception_statement = NULL ; + } + else + { + stashed_exception_code = __gg__exception_code ; + stashed_exception_handled = __gg__exception_handled ; + stashed_exception_file_number = __gg__exception_file_number ; + stashed_exception_file_status = __gg__exception_file_status ; + stashed_exception_file_name = __gg__exception_file_name ; + stashed_exception_program_id = __gg__exception_program_id ; + stashed_exception_section = __gg__exception_section ; + stashed_exception_paragraph = __gg__exception_paragraph ; + stashed_exception_source_file = __gg__exception_source_file ; + stashed_exception_line_number = __gg__exception_line_number ; + stashed_exception_statement = __gg__exception_statement ; + } + } + +extern "C" +void +__gg__float32_from_int128(cblc_field_t *destination, + size_t destination_offset, + cblc_field_t *source, + size_t source_offset, + cbl_round_t rounded, + int *size_error) + { + int rdigits; + _Float128 value = get_binary_value_local( &rdigits, + source, + source->data + source_offset, + source->capacity); + value /= __gg__power_of_ten(rdigits); + + if( fabsf128(value) > 3.4028235E38Q ) + { + if(size_error) + { + *size_error = 1; + } + } + else + { + if(size_error) + { + *size_error = 0; + } + __gg__float128_to_qualified_field(destination, + destination_offset, + value, + rounded, + NULL); + } + } + +extern "C" +void +__gg__float64_from_int128(cblc_field_t *destination, + size_t destination_offset, + cblc_field_t *source, + size_t source_offset, + cbl_round_t rounded, + int *size_error) + { + if(size_error) + { + *size_error = 0; + } + int rdigits; + _Float128 value = get_binary_value_local( &rdigits, + source, + source->data + source_offset, + source->capacity); + value /= __gg__power_of_ten(rdigits); + __gg__float128_to_qualified_field(destination, + destination_offset, + value, + rounded, + NULL); + } + +extern "C" +void +__gg__float128_from_int128(cblc_field_t *destination, + size_t destination_offset, + cblc_field_t *source, + size_t source_offset, + cbl_round_t rounded, + int *size_error) + { + if(size_error) *size_error = 0; + int rdigits; + _Float128 value = get_binary_value_local( &rdigits, + source, + source->data + source_offset, + source->capacity); + value /= __gg__power_of_ten(rdigits); + __gg__float128_to_qualified_field(destination, + destination_offset, + value, + rounded, + NULL); + } + +extern "C" +int +__gg__is_float_infinite(cblc_field_t *source, size_t offset) + { + int retval = 0; + switch(source->capacity) + { + case 4: + retval = fpclassify( *(_Float32*)(source->data+offset)) == FP_INFINITE; + break; + case 8: + retval = fpclassify( *(_Float64*)(source->data+offset)) == FP_INFINITE; + break; + case 16: + // retval = *(_Float128*)(source->data+offset) == INFINITY; + _Float128 t; + memcpy(&t, source->data+offset, 16); + retval = t == INFINITY; + break; + } + return retval; + } + +extern "C" +int +__gg__float32_from_128( cblc_field_t *dest, + size_t dest_offset, + cblc_field_t *source, + size_t source_offset) + { + int retval = 0; + //_Float128 value = *(_Float128*)(source->data+source_offset); + _Float128 value; + memcpy(&value, source->data+source_offset, 16); + if( fabsf128(value) > 3.4028235E38Q ) + { + retval = 1; + } + else + { + *(_Float32 *)(dest->data+dest_offset) = (_Float32)value; + } + return retval; + } + +extern "C" +int +__gg__float32_from_64( cblc_field_t *dest, + size_t dest_offset, + cblc_field_t *source, + size_t source_offset) + { + int retval = 0; + _Float64 value = *(_Float64*)(source->data+source_offset); + if( fabsf128(value) > 3.4028235E38Q ) + { + retval = 1; + } + else + { + *(_Float32 *)(dest->data+dest_offset) = (_Float32)value; + } + return retval; + } + +extern "C" +int +__gg__float64_from_128( cblc_field_t *dest, + size_t dest_offset, + cblc_field_t *source, + size_t source_offset) + { + int retval = 0; + // _Float128 value = *(_Float128*)(source->data+source_offset); + _Float128 value; + memcpy(&value, source->data+source_offset, 16); + if( fabsf128(value) > 1.7976931348623157E308 ) + { + retval = 1; + } + else + { + *(_Float64 *)(dest->data+dest_offset) = (_Float64)value; + } + return retval; + } + +extern "C" +char * +__gg__display_int128(__int128 value) + { + static char ach[64]; + + if( value == 0 ) + { + strcpy(ach, "0"); + return ach; + } + + bool is_negative = false; + if( value < 0 ) + { + is_negative = true; + value = -value; + } + char *p = ach+64; + *--p = '\0'; + + while(value) + { + *--p = value%10 + '0'; + value /= 10; + } + if( is_negative ) + { + *--p = '-'; + } + return p; + } + +typedef struct LV_DATA + { + size_t unique_id; + cblc_field_t *field; + unsigned char *data; + }LV_DATA; + +static std::vector lv_variables; + +extern "C" +void +__gg__push_local_variable(cblc_field_t *field) + { + LV_DATA lv_data; + lv_data.unique_id = __gg__unique_prog_id; + lv_data.field = field; + lv_data.data = field->data; + lv_variables.push_back(lv_data); + } + +extern "C" +void +__gg__pop_local_variables() + { + while( lv_variables.size() + && lv_variables.back().unique_id == __gg__unique_prog_id) + { + lv_variables.back().field->data = lv_variables.back().data; + lv_variables.pop_back(); + } + } + +extern "C" +void +__gg__copy_as_big_endian(unsigned char *dest, unsigned char *source) + { + // copy eight bytes of source to dest, flipping the endianness + for(size_t i=0; i<8; i++) + { + dest[i] = source[7-i]; + } + } + +extern "C" +void +__gg__codeset_figurative_constants() + { + // This routine gets called after the codeset has been changed + *__gg__data_space = internal_space; + *__gg__data_low_values = ascii_to_internal(__gg__low_value_character); + *__gg__data_zeros = internal_0; + *__gg__data_high_values = ascii_to_internal(__gg__high_value_character); + *__gg__data_quotes = ascii_to_internal(__gg__quote_character);; + } + +extern "C" +unsigned char * +__gg__get_figconst_data(cblc_field_t *field) + { + unsigned char *retval = NULL; + cbl_figconst_t figconst = (cbl_figconst_t)(size_t)(field->initial); + switch(figconst) + { + case low_value_e : + retval = __gg__data_low_values; + break; + case zero_value_e : + retval = __gg__data_zeros; + break; + case space_value_e : + retval = __gg__data_space; + break; + case quote_value_e : + retval = __gg__data_quotes; + break; + case high_value_e : + retval = __gg__data_high_values; + break; + case normal_value_e : + fprintf(stderr, "__gg__get_figconst_data(): Weird figconst\n"); + abort(); + break; + case null_value_e: + break; + } + return retval; + } + +extern "C" +void +__gg__set_program_list( int program_id, + char ***prog_list, + PFUNC **prog_pointers) + { + accessible_programs[program_id] = prog_list; + accessible_pointers[program_id] = prog_pointers; + } + +static std::unordered_map already_found; + +static +void * +find_in_dirs(const char *dirs, char *unmangled_name, char *mangled_name) + { + + std::unordered_map::const_iterator it = + already_found.find(unmangled_name); + + if( it != already_found.end() ) + { + return it->second; + } + it = already_found.find(mangled_name); + if( it != already_found.end() ) + { + return it->second; + } + + void *retval = NULL; + if( dirs ) + { + char directory[1024]; + char file[1024]; + const char *p = dirs; + while( !retval && *p ) + { + size_t index = 0; + while( index < sizeof(directory)-1 && *p && *p != ':' ) + { + directory[index++] = *p++; + } + directory[index++] = '\0'; + if( *p == ':' ) + { + p += 1; + } + // directory is the next one for us to check: + DIR *dir = opendir(directory); + if( dir ) + { + while( !retval ) + { + dirent *entry = readdir(dir); + if( !entry ) + { + break; + } + size_t len = strlen(entry->d_name); + if( len > 3 + && entry->d_name[len-3] == '.' + && entry->d_name[len-2] == 's' + && entry->d_name[len-1] == 'o' + ) + { + strcpy(file, directory); + strcat(file, "/"); + strcat(file, entry->d_name); + void *handle = dlopen(file, RTLD_LAZY|RTLD_NODELETE ); + if( handle ) + { + retval = dlsym(handle, unmangled_name); + if( retval ) + { + already_found[unmangled_name] = retval; + break; + } + retval = dlsym(handle, mangled_name); + if( retval ) + { + already_found[mangled_name] = retval; + break; + } + dlclose(handle); + } + } + } + closedir(dir); + } + } + } + return retval; + } + +extern "C" +void * +__gg__function_handle_from_cobpath( char *unmangled_name, char *mangled_name) + { + void *retval = NULL; + + // We search for a function. We check first for the unmangled name, and then + // the mangled name. We do this first for the executable, then for .so + // files in COBPATH, and then for files in LD_LIBRARY_PATH + + static void *handle_executable = NULL; + if( !handle_executable ) + { + handle_executable = dlopen(NULL, RTLD_LAZY); + } + if( !retval ) + { + retval = dlsym(handle_executable, unmangled_name); + } + if( !retval ) + { + retval = dlsym(handle_executable, mangled_name); + } + if( !retval ) + { + const char *COBPATH = getenv("COBPATH"); + retval = find_in_dirs(COBPATH, unmangled_name, mangled_name); + } + if( !retval ) + { + const char *LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH"); + retval = find_in_dirs(LD_LIBRARY_PATH, unmangled_name, mangled_name); + } + + return retval; + } + +extern "C" +void +__gg__just_mangle_name( cblc_field_t *field, + char **mangled_name + ) + { + static char ach_name[1024]; + static char ach_unmangled[1024]; + static char ach_mangled[1024]; + + size_t length; + length = field->capacity; + memcpy(ach_name, field->data, length); + ach_name[length] = '\0'; + + if( internal_is_ebcdic) + { + // The name is in EBCDIC + __gg__ebcdic_to_ascii(ach_name, length); + } + + bool is_pointer = false; + + if( (field && field->type == FldPointer) ) + { + is_pointer = true; + } + + if( is_pointer ) + { + strcpy(ach_name, ""); + } + + // At this point we have a null-terminated ascii function name. + + // Convert it to both unmangled and mangled forms: + strcpy(ach_unmangled, not_mangled_core(ach_name, ach_name+length)); + strcpy(ach_mangled, mangler_core( ach_name, ach_name+length)); + + if( mangled_name ) + { + *mangled_name = ach_mangled; + } + } + +extern "C" +void * +__gg__function_handle_from_literal(int program_id, + char *literal) + { + void *retval = NULL; + static char ach_unmangled[1024]; + static char ach_mangled[1024]; + + size_t length; + + length = strlen(literal); + + // At this point we have a null-terminated ascii function name. + + // Convert it to both unmangled and mangled forms: + strcpy(ach_unmangled, not_mangled_core(literal, literal+length)); + strcpy(ach_mangled, mangler_core( literal, literal+length)); + + int function_index = __gg__routine_to_call(ach_mangled, program_id); + if( function_index > -1 ) + { + std::unordered_map::const_iterator it = + accessible_pointers.find(program_id); + if( it == accessible_pointers.end() ) + { + __gg__abort("__gg__function_handle_from_literal():" + " fell off the end of accessible_pointers"); + } + PFUNC **pointers_p = it->second; + PFUNC *pointers = *pointers_p; + retval = (void *)pointers[function_index]; + } + else + { + retval = __gg__function_handle_from_cobpath(ach_unmangled, ach_mangled); + } + + return retval; + } + +extern "C" +void * +__gg__function_handle_from_name(int program_id, + cblc_field_t *field, + size_t offset, + size_t length ) + { + void *retval = NULL; + static char ach_name[1024]; + static char ach_unmangled[1024]; + static char ach_mangled[1024]; + + if( length == 0 ) + { + length = field->capacity; + } + + memcpy(ach_name, field->data + offset, length); + + if( internal_is_ebcdic) + { + // The name is in EBCDIC + __gg__ebcdic_to_ascii(ach_name, length); + } + + // At this point we have a null-terminated ascii function name. + + // Convert it to both unmangled and mangled forms: + strcpy(ach_unmangled, not_mangled_core(ach_name, ach_name+length)); + strcpy(ach_mangled, mangler_core( ach_name, ach_name+length)); + + int function_index = __gg__routine_to_call(ach_mangled, program_id); + if( function_index > -1 ) + { + std::unordered_map::const_iterator it = + accessible_pointers.find(program_id); + if(it == accessible_pointers.end()) + { + __gg__abort("__gg__function_handle_from_name():" + " fell off the end of accessible_pointers"); + } + PFUNC **pointers_p = it->second; + PFUNC *pointers = *pointers_p; + retval = (void *)pointers[function_index]; + } + else + { + retval = __gg__function_handle_from_cobpath(ach_unmangled, ach_mangled); + } + + return retval; + } + +extern "C" +void +__gg__variables_to_init(cblc_field_t *array[], const char *clear) + { + int i=0; + for(;;) + { + cblc_field_t *field = array[i++]; + if( !field ) + { + break; + } + int flag_bits = 0; + flag_bits |= clear + ? DEFAULTBYTE_BIT + (*clear & DEFAULT_BYTE_MASK) + : 0; + __gg__initialize_variable_clean(field, flag_bits); + } + } + +extern "C" +void +__gg__mirror_range( size_t nrows, + cblc_field_t *src, // The row + size_t src_o, + size_t nspans, // The number of spans + size_t *spans, + size_t table, + size_t ntbl, + size_t *tbls) + { + static std::unordered_map rows_in_table; + static std::unordered_map widths_of_table; + static std::unordered_map> spans_in_table; + + // Let's do the memorization bookkeeping for the target table + // We have to do this every time, because if we have memory, everything gets + // higgledepiggledy when INITIALZE ALL FILLER is followed by + // INITIALIZE ALL VALUE + std::vector spans_this_time(2*nspans); + for(size_t i=0; i<2*nspans; i++) + { + spans_this_time[i] = spans[i]; + } + rows_in_table[table] = nrows; + spans_in_table[table] = spans_this_time; + + // We need to know the width of one row of this table, which is different + // depending on type of src: + + cblc_field_t *parent = src; + while( parent ) + { + if( parent->occurs_upper ) + { + break; + } + } + if( parent == nullptr ) + { + __gg__abort("__gg__mirror_range() parent is NULL"); + } + size_t width; + if( parent->type == FldGroup ) + { + width = parent->capacity; + } + else + { + width = parent->capacity * parent->occurs_upper; + } + widths_of_table[table] = width; + + if( nspans == 0 && ntbl == 0 ) + { + // There are no FILLERS to be skipped, so we can just do our cute line + // duplicating trick. We understand that there isn't actually much in the + // the way of computational savings -- every byte has to be written, after + // all -- but it is satisfying. + size_t stride = src->capacity; + unsigned char *source = src->data + src_o; + unsigned char *dest = source + stride; + nrows -= 1; // This reflects that row[0] equals row[0] + + size_t nrows_this_time = 1; + while(nrows) + { + memcpy(dest, source, nrows_this_time * stride); + dest += nrows_this_time * stride; + nrows -= nrows_this_time; + nrows_this_time *= 2; + nrows_this_time = std::min(nrows_this_time, nrows); + } + } + else + { + size_t stride = src->capacity; + unsigned char *source = src->data + src_o; + unsigned char *dest = source; + + while( nrows-- ) + { + // These spans are for non-table elements + if( nspans == 0 ) + { + // Special case: We have no spans, but in the case of, for example, + // 01 four-by-four2. + // 05 label5 pic x(12) value "four-by-four". + // 05 four-outer2 occurs 4 times. + // 10 four-inner2 occurs 4 times. + // 15 label15 pic x(12) value "four-inner". + // 15 FNAME PIC X(7) VALUE "James". + // 15 FILLER PIC X(7) VALUE "Keen ". + // 15 LNAME PIC X(7) VALUE "Lowden". + // 10 label10 pic x(12) value "four-outer". + // + // the label10 field *should* be a span. The parser doesn't do that, + // though, so we have to: + size_t left = 0; + size_t right = stride; + for(size_t subtable=0; subtable subtable_spans + = spans_in_table [subtable_index]; + + unsigned char *subtable_source = source + subtable_offset; + + if( subtable_spans.size() == 0 ) + { + unsigned char *subtable_dest = dest + subtable_offset; + size_t span_start = 0; + size_t span_end = subtable_stride; + size_t subtable_row = subtable_rows; + while( subtable_row-- ) + { + memcpy(subtable_dest + span_start, + subtable_source + span_start, + span_end - span_start); + subtable_dest += subtable_stride; + } + } + + for(size_t span=0; spandata + offset, + size); + double delay = (double)value / __gg__power_of_ten(rdigits); + if( delay < 0 ) + { + exception_raise(ec_continue_less_than_zero); + delay = 0; + } + + // Convert the time to nanoseconds. + delay = delay * 1000000000; + + // Convert the result to seconds/nanoseconds for nanosleep() + size_t tdelay = (size_t)delay; + timespec duration; + + duration.tv_sec = tdelay / 1000000000; + duration.tv_nsec = tdelay % 1000000000; + + nanosleep(&duration, NULL); + } + +extern "C" +void +__gg__deallocate( cblc_field_t *target, + size_t offset, + int addr_of) + { + if( addr_of || (target->attr & based_e)) + { + // Free the target's data pointer + if( target->data ) + { + free(target->data); + target->data = NULL; + } + } + else if (target->type == FldPointer) + { + // Target is a pointer. Free the data location + int rdigits; + void *ptr = (void *)get_binary_value_local(&rdigits, + target, + target->data + offset, + sizeof(void *)); + if( ptr ) + { + free(ptr); + // And set the data location to zero + *(char **)(target->data + offset) = NULL; + } + } + } + +static int +get_the_byte(cblc_field_t *field) + { + int retval = -1; + if( field ) + { + cbl_figconst_t figconst = (cbl_figconst_t)(field->attr & FIGCONST_MASK); + switch(figconst) + { + case null_value_e: + retval = 0; + break; + case low_value_e: + retval = ascii_to_internal(__gg__low_value_character); + break; + case zero_value_e: + retval = internal_zero; + break; + case space_value_e: + retval = internal_space; + break; + case quote_value_e: + retval = ascii_to_internal(__gg__quote_character); + break; + case high_value_e: + retval = ascii_to_internal(__gg__high_value_character) & 0xFF; + break; + case normal_value_e: + retval = (int)__gg__get_integer_binary_value(field); + break; + } + } + return retval; + } + +extern "C" +void +__gg__allocate( cblc_field_t *first, + size_t first_offset, + int initialized, + int default_byte, + cblc_field_t *f_working_byte, + cblc_field_t *f_local_byte, + cblc_field_t *returning, + size_t returning_offset) + { + int working_byte = get_the_byte(f_working_byte); + int local_byte = get_the_byte(f_local_byte); + + unsigned char *retval = NULL; + if( first->attr & based_e ) + { + // first is the BASED variable we are allocating memory for + if( first->capacity ) + { + retval = (unsigned char *)malloc(first->capacity); + + if( initialized ) + { + // This is ISO 2023 ALLOCATE rule 7 (ALL TO VALUE) + int fill_char = 0; + if( default_byte >= 0 ) + { + fill_char = default_byte; + memset(retval, fill_char, first->capacity); + } + } + else + { + // This is ISO 2023 ALLOCATE rule 9 (pointers NULL, otherwise OPT_INIT) + int fill_char = 0; + if( default_byte >= 0 ) + { + fill_char = default_byte; + } + if( first->attr & (linkage_e | local_e) ) + { + if( local_byte >= 0 ) + { + fill_char = local_byte; + } + } + else + { + if( working_byte >= 0 ) + { + fill_char = working_byte; + } + } + memset(retval, fill_char, first->capacity); + } + } + first->data = retval; + } + else + { + // This is an ALLOCATE CHARACTERS + // first contains the number of bytes to allocate + int rdigits; + ssize_t tsize = (ssize_t)get_binary_value_local(&rdigits, + first, + first->data + first_offset, + sizeof(void *)); + tsize = std::max(0L, tsize); + size_t pof10 = __gg__power_of_ten(rdigits); + + // If there are any non-zero digits to the right of the decimal point, + // increment the units place: + tsize += (pof10-1); + + // Adjust the result to be an integer. + tsize /= pof10; + if( tsize ) + { + retval = (unsigned char *)malloc(tsize); + + int fill_char = 0; + if( initialized ) + { + // This is ISO 2023 rule 6 (defaultbyte if specified, else zero) + if( default_byte >= 0 ) + { + fill_char = default_byte; + } + } + else + { + // This is ISO 2023 rule 8 (OPT_INIT if specified, otherwise defaultbyte, otherwise zero)") + if( default_byte >= 0 ) + { + fill_char = default_byte; + } + if( first->attr & (linkage_e | local_e) ) + { + if( local_byte >= 0 ) + { + fill_char = local_byte; + } + } + else + { + if( working_byte >= 0 ) + { + fill_char = working_byte; + } + } + } + + memset(retval, fill_char, tsize); + } + } + + if( returning ) + { + // 'returning' has to be a FldPointer variable; assign the retval to it. + *(unsigned char **)(returning->data + returning_offset) = retval; + } + } + +static std::vectormodule_name_stack; + +extern "C" +void +__gg__module_name_push(const char *module_name) + { + module_name_stack.push_back(module_name); + } + +extern "C" +void +__gg__module_name_pop() + { + if( module_name_stack.size() == 0 ) + { + __gg__abort("__gg__module_name_pop(): module_name_stack is empty"); + } + module_name_stack.pop_back(); + } + +extern "C" +void +__gg__module_name(cblc_field_t *dest, module_type_t type) + { + static size_t result_size = 64; + static char *result = (char *)malloc(result_size); + + strcpy(result, ""); + + size_t ssize = module_name_stack.size(); + + switch( type ) + { + case module_activating_e: + /* 5) If the ACTIVATING keyword is specified and the function is in a COBOL + main program, then the returned value shall be a single space. The + implementor shall document how a main program is identified. If the function + is not specified in a main program, then the returned value is the name of + the runtime element that activated the currently running runtime element. + This may be by a CALL statement, an INVOKE statement, a function reference, + or an inline invocation. */ + + /* 6) If the ACTIVATING keyword is specified and the activating statement + is within a nested program, then it is implementor defined what value is + returned. This may be the name of the nested program or the name of the + outermost program containing the nested program. */ + + switch( module_name_stack.back()[0] ) + { + case 'T': + // We are in a top-level program, not nested: + if( module_name_stack.size() == 1 + || (module_name_stack.size() == 2 + && module_name_stack.front()[0] == 'M' ) ) + { + // This is a "main program", so we return a single space. + strcpy(result, " "); + } + else + { + // This is a called program, so we return the name of the "runtime + // element" that called us: + strcpy(result, module_name_stack[ssize-2].substr(1).c_str()); + } + break; + + case 'N': + // We are in a nested function. + { + // This is a called program, so we return the name of the program that + // called us + strcpy(result, module_name_stack[ssize-2].substr(1).c_str()); + } + } + break; + + case module_current_e: + // 7) If the CURRENT keyword is specified then the returned value is the + // name of the runtime element of the outermost program of the compilation + // unit’s code that is currently running. + + // Look upward for our parent T. + // Termination is weird because size_t is unsigned + for(size_t i=ssize-1; i result_size) + { + result_size *= 2; + result = (char *)realloc(result, result_size); + } + strcat(result, module_name_stack[i].substr(1).c_str()); + strcat(result, ";"); + } + } + strcat(result, " "); + + break; + + case module_toplevel_e: + { + size_t i = 0; + if( module_name_stack[i] == "Mmain" ) + { + i += 1; + } + strcpy(result, module_name_stack[i].substr(1).c_str()); + } + break; + } + +__gg__adjust_dest_size(dest, strlen(result)); + memcpy(dest->data, result, strlen(result)+1); + } + diff --git a/libgcobol/libgcobol.h b/libgcobol/libgcobol.h new file mode 100644 index 00000000000..bd9446adf60 --- /dev/null +++ b/libgcobol/libgcobol.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef LIBGCOBOL_H_ +#define LIBGCOBOL_H_ + +#include + +#include +#include +#include + +#define MIN_FIELD_BLOCK_SIZE (16) + +// RUNTIME structures *must* match the ones created in structs.c and initialized +// and used in genapi.c. It's actually not all that important to emphasize that +// fact, since the compiled executable will crash and burn quickly if they don't +// match precisely. + +// Note that it must match the same structure in the GDB-COBOL debugger + +#define A_ZILLION (1000000) // Absurdly large number for __gg__call_parameter_count + +// These bits are used for the "call flags" of arithmetic operations +#define ON_SIZE_ERROR 0x01 +#define REMAINDER_PRESENT 0x02 + +/* 'offset' is overloaded for FldAlphanumeric/temporary/intermediate variables + * For such variables, offset is a copy of the initial capacity. This is in + * support of the FUNCTION TRIM function, which both needs to be able to + * reduce the capacity of the target variable, and then to reset it back to + * the original value + */ + +enum substitute_flags_t + { + substitute_anycase_e = 1, + substitute_first_e = 2, // first and last are mutually exclusive + substitute_last_e = 4, + }; + +enum cblc_file_flags_t + { + file_flag_optional_e = 0x00001, + file_flag_existed_e = 0x00002, + file_name_quoted_e = 0x00004, + file_flag_initialized_e = 0x00008, + }; + +// For indexed files, there can be one or more indexes, one per key. +// Each index is one or more fields. + +struct file_hole_t + { + long location; + size_t size; + }; + +struct file_index_t + { + std::multimap, long> key_to_position; + std::multimap, long>::iterator current_iterator; + std::multimap, long>::iterator ending_iterator; + }; + +class supplemental_t + { + public: + std::vector holes; + std::vector indexes; + std::vector uniques; + }; + +struct cblc_subscript_t + { + cblc_field_t *field; // That's what it usually is: + unsigned int type; // When type is FldLiteralN, field is a pointer to __int128 + }; + +#define REFER_T_ALL_FLAGS_MASK 0x0FF // We allow for seven subscripts +#define REFER_T_MOVE_ALL 0x100 // This is the move_all flag +#define REFER_T_ADDRESS_OF 0x200 // This is the address_of flag + +struct cblc_declarative_t + { + int format; + int culprit; //declarative_culprit_t + int nfiles; + }; + +/* According to the standard, the first digit of the file operation status + register is interpreted like this: + + EC-I-O-AT-END '1' + EC-I-O-INVALID-KEY '2' + EC-I-O-PERMANENT-ERROR '3' + EC-I-O-LOGIC-ERROR '4' + EC-I-O-RECORD-OPERATION '5' + EC-I-O-FILE-SHARING '6' + EC-I-O-IMP '9' + +When the tens digit is '0', there are a number of conditions for +successful completion. See section 9.1.12.1 + + 00 unqualified success + 02 duplicate key detected + 04 the data read were either too short or too long + 05 the operator couldn't find the tape + 07 somebody tried to rewind the card reader. + +For now, I am going to treat the io_status as an integer 00 through 99. I +anticipate mostly returning + 00 for ordinary success, + 04 for a mismatched record size + 10 for an end-of-file + +*/ + +// This global variable is constantly being updated with the yylineno. This is +// useful for creating error messages, and for handling EXCEPTION_CONDITIONS +extern int __gg__exception_code; +extern int __gg__exception_line_number; +extern int __gg__exception_file_status; +extern const char *__gg__exception_file_name; +extern const char *__gg__exception_statement; +extern const char *__gg__exception_source_file; +extern const char *__gg__exception_program_id; +extern const char *__gg__exception_section; +extern const char *__gg__exception_paragraph; + +extern "C" void __gg__set_exception_code( ec_type_t ec, + int from_raise_statement=0); + +extern int * __gg__fourplet_flags; + +extern cblc_field_t ** __gg__treeplet_1f; +extern size_t * __gg__treeplet_1o; +extern size_t * __gg__treeplet_1s; +extern cblc_field_t ** __gg__treeplet_2f; +extern size_t * __gg__treeplet_2o; +extern size_t * __gg__treeplet_2s; +extern cblc_field_t ** __gg__treeplet_3f; +extern size_t * __gg__treeplet_3o; +extern size_t * __gg__treeplet_3s; +extern cblc_field_t ** __gg__treeplet_4f; +extern size_t * __gg__treeplet_4o; +extern size_t * __gg__treeplet_4s; + +#if 1 + static inline + void exception_raise(ec_type_t ec_code) { __gg__set_exception_code(ec_code); } +#else +# define exception_raise(ec_code)do{__gg__set_exception_code(ec_code);}while(0); +#endif + +extern "C" __int128 __gg__power_of_ten(int n); + +extern "C" __int128 __gg__dirty_to_binary_source( const char *dirty, + int length, + int *rdigits); +extern "C" __int128 __gg__dirty_to_binary_internal( const char *dirty, + int length, + int *rdigits); +extern "C" __int128 __gg__binary_value_from_field( int *rdigits, + cblc_field_t *var); +extern "C" int __gg__compare_2( cblc_field_t *left_side, + unsigned char *left_location, + size_t left_length, + int left_attr, + bool left_all, + bool left_address_of, + cblc_field_t *right_side, + unsigned char *right_location, + size_t right_length, + int right_attr, + bool right_all, + bool right_address_of, + int second_time_through); +extern "C" void __gg__int128_to_field(cblc_field_t *tgt, + __int128 value, + int source_rdigits, + enum cbl_round_t rounded, + int *compute_error); +extern "C" void __gg__float128_to_field(cblc_field_t *tgt, + _Float128 value, + enum cbl_round_t rounded, + int *compute_error); +extern "C" void __gg__int128_to_qualified_field(cblc_field_t *tgt, + size_t offset, + size_t length, + __int128 value, + int source_rdigits, + enum cbl_round_t rounded, + int *compute_error); +extern "C" void __gg__float128_to_qualified_field(cblc_field_t *tgt, + size_t tgt_offset, + _Float128 value, + enum cbl_round_t rounded, + int *compute_error); + +extern "C" void __gg__double_to_target( cblc_field_t *tgt, + double tgt_value, + cbl_round_t rounded); +extern "C" char __gg__get_decimal_separator(); +extern "C" char __gg__get_decimal_point(); +extern "C" char * __gg__get_default_currency_string(); + +extern "C" void __gg__clock_gettime(clockid_t clk_id, struct timespec *tp); +extern "C" _Float128 __gg__float128_from_location(cblc_field_t *var, + unsigned char *location); +extern "C" void __gg__adjust_dest_size(cblc_field_t *dest, size_t ncount); +#define MINIMUM_ALLOCATION_SIZE 16 +extern "C" void __gg__realloc_if_necessary( char **dest, + size_t *dest_size, + size_t new_size); +extern "C" void __gg__set_exception_file(cblc_file_t *file); +extern "C" void __gg__internal_to_console_in_place(char *loc, size_t length); +extern "C" __int128 __gg__binary_value_from_qualified_field(int *rdigits, + cblc_field_t *var, + size_t offset, + size_t size); +extern "C" _Float128 __gg__float128_from_qualified_field(cblc_field_t *field, + size_t offset, + size_t size); +extern "C" __int128 __gg__integer_from_qualified_field(cblc_field_t *var, + size_t var_offset, + size_t var_size); +void __gg__abort(const char *msg); + + +#endif diff --git a/libgcobol/valconv.cc b/libgcobol/valconv.cc new file mode 100644 index 00000000000..02dd3cc5500 --- /dev/null +++ b/libgcobol/valconv.cc @@ -0,0 +1,1721 @@ +// This file is included in both the libgcobol and gcc/cobol compilations +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "common-defs.h" +#include "io.h" +#include "gcobolio.h" +#include "libgcobol.h" +#include "gfileio.h" +#include "charmaps.h" + +#include +#include +#include + +#include "valconv.h" +#include "exceptl.h" + +int __gg__decimal_point = '.' ; +int __gg__decimal_separator = ',' ; +int __gg__quote_character = '"' ; +int __gg__low_value_character = 0x00 ; +int __gg__high_value_character = 0xFF ; +char **__gg__currency_signs ; + +int __gg__default_currency_sign; + +char *__gg__ct_currency_signs[256]; // Compile-time currency signs + +std::unordered_map __gg__alphabet_states; + +extern "C" +void +__gg__realloc_if_necessary(char **dest, size_t *dest_size, size_t new_size) + { + if( new_size > *dest_size ) + { + // Find the next power of two bigger than us: + new_size |= new_size>>1; + new_size |= new_size>>2; + new_size |= new_size>>4; + new_size |= new_size>>8; + new_size |= new_size>>16; + new_size |= new_size>>32; + *dest_size = new_size + 1; + *dest = (char *)realloc(*dest, *dest_size); + } + } + +extern "C" +void +__gg__alphabet_create( cbl_encoding_t encoding, + size_t alphabet_index, + unsigned char *alphabet, + int low_char, + int high_char ) + { + assert( encoding == custom_encoding_e ); + + std::unordered_map::const_iterator it = + __gg__alphabet_states.find(alphabet_index); + + if( it == __gg__alphabet_states.end() ) + { + alphabet_state new_state; + new_state.low_char = low_char; + new_state.high_char = high_char; + + for(int i=0; i<256; i++) + { + if( alphabet[i] != 0xFF ) + { + new_state.collation[i] = alphabet[i] ; + } + else + { + // Use a value bigger than HIGH, but which will sort according to the + // original character-based order. + new_state.collation[i] = 256 + i; + } + } + __gg__alphabet_states[alphabet_index] = new_state; + } + + return; + } + + +static int +expand_picture(char *dest, const char *picture) + { + // 'dest' must be of adequate length to hold the expanded picture string, + // including any extra characters due to a CURRENCY SIGN expansion. + + int ch; + int prior_ch = NULLCH; + char *d = dest; + const char *p = picture; + + long repeat; + + int currency_symbol = NULLCH; + + while( (ch = (*p++ & 0xFF) ) ) + { + if( ch == ascii_oparen ) + { + // Pick up the number after the left parenthesis + char *endchar; + repeat = strtol(p, &endchar, 10); + + // We subtract one because we know that the character just before + // the parenthesis was already placed in dest + repeat -= 1; + + // Update p to the character after the right parenthesis + p = endchar + 1; + while(repeat--) + { + *d++ = prior_ch; + } + } + else + { + prior_ch = ch; + *d++ = ch; + } + + if( __gg__currency_signs[ch] ) + { + // We are going to be mapping ch to a string in the final result: + prior_ch = ch; + currency_symbol = ch; + } + } + + size_t dest_length = d-dest; + + // We have to take into account the possibility that the currency symbol + // mapping might be to a string of more than one character: + + if( currency_symbol ) + { + size_t sign_length = strlen(__gg__currency_signs[currency_symbol]) - 1; + if( sign_length ) + { + char *pcurrency = strchr(dest, currency_symbol); + assert(pcurrency); + memmove( pcurrency + sign_length, + pcurrency, + dest_length - (pcurrency-dest)); + for(size_t i=0; i= 2 ) + { + // It's a positive number, so we might have to get rid of a CR or DB: + char ch1 = toupper(dest[dlength-2]); + char ch2 = toupper(dest[dlength-1]); + if( (ch1 == ascii_D && ch2 == ascii_B) + || (ch1 == ascii_C && ch2 == ascii_R) ) + { + if( !is_negative ) + { + // Per the spec, because the number is positive, those two + // characters become blank: + dest[dlength-2] = ascii_space; + dest[dlength-1] = ascii_space; + } + // Trim the dlength by two to reflect those two positions at the + // right edge, and from here on out we can ignore them. + dlength -= 2; + } + } + + // We need to know if we have a currency picture symbol in this string: + // This is the currency character in the PICTURE + unsigned char currency_picture = NULLCH; + const char *currency_sign = NULL; // This is the text we output when + // // encountering the currency_picture + // // character + // Note that the currency_picture can be upper- or lower-case, which is why + // we can't treat dest[] to toupper. That makes me sad, because I have + // to do some tests for upper- and lower-case Z, and so on. + for(int i=0; i non_native_zeros ) + { + non_native_zeros = nines; + nonzero_index = slength - non_native_zeros; + if( nonzero_index < 0 ) + { + nonzero_index = 0; + } + } + // nonzero_index is now the location of the leftmost digit that we will + // output as a digit. Everything to its left is a leading zero, and might + // get replaced with a floating replacement. + + // We are now in a position to address specific situations: + + // This is the case of leading zero suppression + if( (strchr(picture, ascii_Z)) || (strchr(picture, ascii_z)) ) + { + int leftmost_indexA = Lindex(dest, dlength, ascii_Z); + int leftmost_indexB = Lindex(dest, dlength, ascii_z); + if( leftmost_indexA == -1 ) + { + leftmost_indexA = leftmost_indexB; + } + if( leftmost_indexB == -1 ) + { + leftmost_indexB = leftmost_indexA; + } + + int rightmost_indexA = Lindex(dest, dlength, ascii_Z); + int rightmost_indexB = Lindex(dest, dlength, ascii_z); + if( rightmost_indexA == -1 ) + { + rightmost_indexA = leftmost_indexB; + } + if( rightmost_indexB == -1 ) + { + rightmost_indexB = leftmost_indexA; + } + + int leftmost_index = std::min(leftmost_indexA, leftmost_indexB); + int rightmost_index = std::max(rightmost_indexA, rightmost_indexB); + + // We are doing replacement editing: leading zeroes get replaced with + // spaces. + if( is_zero && nines == 0 ) + { + // Corner case: The value is zero, and all numeric positions + // are suppressed. The result is all spaces: + memset(dest, ascii_space, dlength); + } + else + { + int index_s = slength-1; // Index into source string of digits + int index_d = dlength-1; // Index into the destination + bool reworked_string = false; + + while(index_d >=0) + { + // Pick up the destination character that we will replace: + char ch_d = dest[index_d]; + + if( ch_d == currency_picture ) + { + // We are going to lay down the currency string. Keep + // in mind that our caller nicely left room for it + size_t sign_len = strlen(currency_sign); + while(sign_len > 0) + { + dest[index_d--] = currency_sign[--sign_len]; + } + continue; + } + + char ch_s; + if( index_s < 0 ) + { + // I don't think this can happen, but just in case: + ch_s = ascii_zero; + } + else + { + ch_s = source[index_s]; + } + + if( index_s <= nonzero_index && !reworked_string) + { + reworked_string = true; + // index_s is the location of the leftmost non-zero + // digit. + + // So, we are about to enter the world of leading + // zeroes. + + // The specification says, at this point, that + // all B 0 / , and . inside the floating string + // are to be considered part of the floating string: + + // So, we edit dest[] to make that true: + int rlim = rightmost_index > index_d ? index_d : rightmost_index; + + for(int i=leftmost_index; i= decimal_point_index ) + { + // We are to the right of the decimal point, and so we + // don't do any replacement. We either insert a character, + // or we replace with a digit: + switch(ch_d) + { + // We are to the right of the decimal point, so Z is + // a character position + case ascii_z: + case ascii_Z: + case ascii_nine: + index_s -= 1; + break; + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + case ascii_plus: + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + break; + case ascii_minus: + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + break; + case ascii_P: + case ascii_p: + // P-scaling has been handled by changing the value + // and the number of rdigits, so these characters + // are ignored here: + break; + default: + // Valid possibilities are 0 / , + // Just leave them be + ch_s = ch_d; + break; + } + dest[index_d] = ch_s; + } + else + { + // We are to the left of the decimal point: + if( ch_d == __gg__decimal_point ) + { + // Do this assignment to handle the situation where + // period and comma have been swapped. It's necessary + // because the case statement can't take a variable + ch_s = __gg__decimal_point; + } + else + { + switch(ch_d) + { + case ascii_nine: + index_s -= 1; + break; + case ascii_v: + case ascii_V: + ch_s = __gg__decimal_point; + break; + case ascii_plus: + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + break; + case ascii_minus: + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + break; + + case ascii_z: + case ascii_Z: + if( index_s < nonzero_index) + { + // We are in the leading zeroes, so they are + // replaced with a space + ch_s = ascii_space; + } + index_s -= 1; + break; + + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + + default: + // Valid possibilities are 0 / , which + // at this point all get replaced with spaces: + if( index_s < nonzero_index) + { + // We are in the leading zeroes, so they are + // replaced with a space + ch_s = ascii_space; + } + else + { + // We still have digits to send out, so the output + // is a copy of the PICTURE string + ch_s = ch_d; + } + } + } + dest[index_d] = ch_s; + } + + index_d -= 1; + } + } + } + + // This is the case of leading zero replacement: + else if( strchr(picture, ascii_asterisk) ) + { + int leftmost_index = Lindex(dest, dlength, ascii_asterisk); + int rightmost_index = Rindex(dest, dlength, ascii_asterisk); + // We are doing replacement editing: leading zeroes get replaced with + // asterisks, except that any decimal point is put into place: + if( is_zero && nines == 0 ) + { + // We need to re-initialize dest, because of the possibility + // of a CR/DB at the end of the line + dlength = expand_picture(dest, picture); + + for(int i=0; i=0) + { + // Pick up the destination character that we will replace: + char ch_d = dest[index_d]; + + if( ch_d == currency_picture ) + { + // We are going to lay down the currency string. Keep + // in mind that our caller nicely left room for it + size_t sign_len = strlen(currency_sign); + while(sign_len > 0) + { + dest[index_d--] = currency_sign[--sign_len]; + } + continue; + } + + char ch_s; + if( index_s < 0 ) + { + // I don't think this can happen, but just in case: + ch_s = ascii_zero; + } + else + { + ch_s = source[index_s]; + } + + if( index_s <= nonzero_index && !reworked_string) + { + reworked_string = true; + // index_s is the location of the leftmost non-zero + // digit. + + // So, we are about to enter the world of leading + // zeroes. + + // The specification says, at this point, that + // all B 0 / , and . inside the floating string + // are to be considered part of the floating string: + + // So, we edit dest[] to make that true: + int rlim = rightmost_index > index_d ? index_d : rightmost_index; + + for(int i=leftmost_index; i= decimal_point_index ) + { + // We are to the right of the decimal point, and so we + // don't do any replacement. We either insert a character, + // or we replace with a digit: + switch(ch_d) + { + // We are to the right of the decimal point, so asterisk + // is a a character position + case ascii_asterisk: + case ascii_nine: + index_s -= 1; + break; + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + case ascii_plus: + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + break; + case ascii_minus: + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + break; + default: + // Valid possibilities are 0 / , + // Just leave them be + ch_s = ch_d; + break; + } + dest[index_d] = ch_s; + } + else + { + // We are to the left of the decimal point: + if( ch_d == __gg__decimal_point ) + { + ch_s = __gg__decimal_point; + } + else + { + switch(ch_d) + { + case ascii_nine: + index_s -= 1; + break; + case ascii_v: + case ascii_V: + ch_s = __gg__decimal_point; + break; + case ascii_plus: + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + break; + case ascii_minus: + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + break; + + case ascii_asterisk: + if( index_s < nonzero_index) + { + // We are in the leading zeroes, so they are + // replaced with an asterisk + ch_s = ascii_asterisk; + } + index_s -= 1; + break; + + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + + default: + // Valid possibilities are 0 / , which + // at this point all get replaced with spaces: + if( index_s < nonzero_index) + { + // We are in the leading zeroes, so they are + // replaced with our suppression character + ch_s = ascii_asterisk; + } + else + { + // We still have digits to send out, so the output + // is a copy of the PICTURE string + ch_s = ch_d; + } + } + } + dest[index_d] = ch_s; + } + + index_d -= 1; + } + } + } + else + { + // At this point, we check for a floating $$, ++, or -- + unsigned char floating_character = 0; + + int leftmost_index; + int rightmost_index; + + leftmost_index = Lindex(dest, dlength, ascii_plus); + rightmost_index = Rindex(dest, dlength, ascii_plus); + if( rightmost_index > leftmost_index) + { + floating_character = ascii_plus; + goto got_float; + } + + leftmost_index = Lindex(dest, dlength, ascii_minus); + rightmost_index = Rindex(dest, dlength, ascii_minus); + if( rightmost_index > leftmost_index) + { + floating_character = ascii_minus; + goto got_float; + } + + leftmost_index = Lindex(dest, dlength, currency_picture); + rightmost_index = Rindex(dest, dlength, currency_picture); + if( rightmost_index > leftmost_index) + { + floating_character = currency_picture; + goto got_float; + } +got_float: + + if( floating_character ) + { + if( is_zero && nines == 0 ) + { + // Special case: + memset(dest, ascii_space, dlength); + } + else + { + const char *decimal_location = index(dest, __gg__decimal_point); + if( !decimal_location ) + { + decimal_location = index(dest, ascii_v); + } + if( !decimal_location ) + { + decimal_location = index(dest, ascii_V); + } + if( !decimal_location ) + { + decimal_location = dest + dlength; + } + int decimal_index = (int)(decimal_location - dest); + + if( rightmost_index > decimal_index ) + { + rightmost_index = decimal_index -1; + } + + int index_s = slength-1; // Index into source string of digits + int index_d = dlength-1; // Index into the destination + bool in_float_string = false; + bool reworked_string = false; + + while(index_d >=0) + { + // Pick up the destination character that we will replace: + unsigned char ch_d = dest[index_d]; + char ch_s = ascii_caret; // Flag this as being replaced + + if( index_d == leftmost_index ) + { + // At this point ch_d is the leftmost floating_character, + // which means it *must* go into the output stream, + // and that means we are truncating any remaining input. + + // Setting nonzero_index to be one character to the right + // means that the following logic will think that any + // source characters from here on out are zeroes + nonzero_index = index_s+1; + } + + if( ch_d != floating_character && ch_d == currency_picture ) + { + // This is a non-floating currency_picture characger + // We are going to lay down the currency string. Keep + // in mind that our caller nicely left room for it + size_t sign_len = strlen(currency_sign); + while(sign_len > 0) + { + dest[index_d--] = currency_sign[--sign_len]; + } + continue; + } + if( ch_d != floating_character && ch_d == ascii_plus ) + { + // This is a non-floating plus sign + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + dest[index_d--] = ch_s; + continue; + } + if( ch_d != floating_character && ch_d == ascii_minus ) + { + // This is a non-floating minus sign + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + dest[index_d--] = ch_s; + continue; + } + + if( index_s < 0 ) + { + // I don't think this can happen, but just in case: + ch_s = ascii_zero; + } + else + { + ch_s = source[index_s]; + if( index_s <= nonzero_index && !reworked_string) + { + reworked_string = true; + // index_s is the location of the leftmost non-zero + // digit. + + // So, we are about to enter the world of leading + // zeroes. + + // The specification says, at this point, that + // all B 0 / , and . inside the floating string + // are to be considered part of the floating string: + + // So, we edit dest[] to make that true: + int rlim = rightmost_index > index_d ? index_d : rightmost_index; + + for(int i=leftmost_index; i= decimal_point_index ) + { + // We are to the right of the decimal point, and so we + // don't do any replacement. We either insert a character, + // or we replace with a digit: + switch(ch_d) + { + case ascii_nine: + index_s -= 1; + break; + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + default: + if( ch_d == floating_character ) + { + // We are laying down a digit + index_s -= 1; + } + else + { + // Valid possibilities are 0 / , + // Just leave them be + ch_s = ch_d; + } + break; + } + dest[index_d] = ch_s; + } + else + { + // We are to the left of the decimal point: + + if( ch_d == __gg__decimal_point ) + { + ch_s = __gg__decimal_point; + } + else if (ch_d == floating_character) + { + if( index_s < nonzero_index ) + { + // We are in the leading zeroes. + if( !in_float_string ) + { + in_float_string = true; + // We have arrived at the rightmost floating + // character in the leading zeroes + + if( floating_character == currency_picture ) + { + size_t sign_len = strlen(currency_sign); + while(sign_len > 0) + { + dest[index_d--] = currency_sign[--sign_len]; + } + continue; + } + if( floating_character == ascii_plus ) + { + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + dest[index_d--] = ch_s; + continue; + } + if( floating_character == ascii_minus ) + { + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + dest[index_d--] = ch_s; + continue; + } + } + else + { + // We are in the leading zeros and the + // floating character location is to our + // right. So, we put down a space: + dest[index_d--] = ascii_space; + continue; + } + } + else + { + // We hit a floating character, but we aren't + // yet in the leading zeroes + index_s -= 1; + dest[index_d--] = ch_s; + continue; + } + } + + if( ch_d == __gg__decimal_point) + { + ch_s = __gg__decimal_point; + } + else + { + switch(ch_d) + { + case ascii_nine: + index_s -= 1; + break; + case ascii_v: + case ascii_V: + ch_s = __gg__decimal_point; + break; + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + + default: + // Valid possibilities are 0 / , which + // at this point all get replaced with spaces: + if( index_s < nonzero_index) + { + // We are in the leading zeroes, so they are + // replaced with our suppression character + ch_s = ascii_space; + } + else + { + // We still have digits to send out, so the output + // is a copy of the PICTURE string + ch_s = ch_d; + } + } + } + dest[index_d] = ch_s; + } + + index_d -= 1; + } + } + } + else + { + // Simple replacement editing + int index_s = slength-1; // Index into source string of digits + int index_d = dlength-1; // Index into the destination + + while(index_d >=0) + { + // Pick up the destination character that we will replace: + char ch_d = dest[index_d]; + + if( ch_d == currency_picture ) + { + // We are going to lay down the currency string. Keep + // in mind that our caller nicely left room for it + size_t sign_len = strlen(currency_sign); + while(sign_len > 0) + { + dest[index_d--] = currency_sign[--sign_len]; + } + continue; + } + + char ch_s; + if( index_s < 0 ) + { + // I don't think this can happen, but just in case: + ch_s = ascii_zero; + } + else + { + ch_s = source[index_s]; + } + switch(ch_d) + { + // We are to the right of the decimal point, so Z is + // a character position + case ascii_nine: + index_s -= 1; + break; + case ascii_b: + case ascii_B: + ch_s = ascii_space; + break; + case ascii_plus: + if( !is_negative ) + { + ch_s = ascii_plus; + } + else + { + ch_s = ascii_minus; + } + break; + case ascii_minus: + if( !is_negative ) + { + ch_s = ascii_space; + } + else + { + ch_s = ascii_minus; + } + break; + default: + // Valid possibilities are 0 / , + // Just leave whatever is here alone + ch_s = ch_d; + break; + } + dest[index_d--] = ch_s; + } + } + } + bool retval = false; + + return retval; + } + +extern "C" +void +__gg__string_to_alpha_edited( char *dest, + char *source, + int slength, + char *picture) + { + // Put the PICTURE into the data area. If the caller didn't leave enough + // room, well, poo on them. Said another way; if they specify disaster, + // disaster is what they will get. + + // This routine expands picture into dest using ascii characters, but + // replaces them with internal characters + + int destlength = expand_picture(dest, picture); + + int dindex = 0; + int sindex = 0; + + while( dindex < destlength ) + { + char dch = dest[dindex]; + char sch; + switch(dch) + { + case ascii_b: // Replaced with space + case ascii_B: + dest[dindex] = internal_space; + break; + + case ascii_zero: // These are left alone: + dest[dindex] = ascii_to_internal(ascii_zero); + break; + + case ascii_slash: + dest[dindex] = ascii_to_internal(ascii_slash); + break; + + default: + // We assume that the parser isn't giving us a bad PICTURE + // string, which means this character should be X, A, or 9 + // We don't check; we just replace it: + if(sindex < slength) + { + sch = source[sindex++]; + } + else + { + sch = internal_space; + } + dest[dindex] = sch; + } + dindex += 1; + } + } + +extern "C" +void +__gg__currency_sign_init() + { + for(int symbol=0; symbol<256; symbol++) + { + if( __gg__currency_signs[symbol] ) + { + free(__gg__currency_signs[symbol]); + __gg__currency_signs[symbol] = NULL; + } + } + } + +extern "C" +void +__gg__currency_sign(int symbol, const char *sign) + { + __gg__currency_signs[symbol] = strdup(sign); + __gg__default_currency_sign = *sign; + } + +extern "C" +void +__gg__remove_trailing_zeroes(char *p) + { + // *p is a floating point number created by strfromN. There will be no + // leading spaces nor unnecessary leading zeroes, but there could be trailing + // zeroes, e.g. 123.456000 or 1.23456000E2 + // Remove the trailing zeroes: + if( *p == '-' ) + { + p += 1; + } + char *left = p; + char *right; + char *pE = strchr(p, 'E'); + if( pE ) + { + right = pE - 1; + } + else + { + right = p + strlen(p)-1; + } + + if( strchr(left, '.') ) + { + while(*right == '0' || *right == internal_space) + { + right -= 1; + } + if( *right == '.' ) + { + right -= 1; + } + } + + right += 1; + memmove(p, left, right-left); + if( pE ) + { + memmove(p + (right-left), pE, strlen(pE)+1); + } + else + { + p[right-left] = '\0'; + } + } + +// This is a convenient place to put this table, since it is used in both the +// run-time and compile-time code, and this source code module is one of the +// ones that are copied from ./libgcobol to gcc/cobol as part of the build. + +ec_descr_t __gg__exception_table[] = { + { ec_all_e, ec_category_none_e, + "EC-ALL", "Any exception" }, + + { ec_argument_e, ec_category_none_e, + "EC-ARGUMENT", "Argument error" }, + { ec_argument_function_e, ec_category_fatal_e, + "EC-ARGUMENT-FUNCTION", "Function argument error" }, + { ec_argument_imp_e, uc_category_implementor_e, + "EC-ARGUMENT-IMP", "Implementor-defined argument error" }, + + { ec_argument_imp_command_e, uc_category_implementor_e, + "EC-ARGUMENT-IMP-COMMAND", "COMMAND-LINE Subscript out of bounds" }, + { ec_argument_imp_environment_e, uc_category_implementor_e, + "EC-ARGUMENT-IMP-ENVIRONMENT", "Envrionment Variable is not defined" }, + + { ec_bound_e, ec_category_none_e, + "EC-BOUND", "Boundary violation" }, + { ec_bound_func_ret_value_e, uc_category_nonfatal_e, + "EC-BOUND-FUNC-RET-VALUE", + "Intrinsic function output does not fit in returned value item" }, + { ec_bound_imp_e, uc_category_implementor_e, + "EC-BOUND-IMP", "Implementor-defined boundary violation" }, + { ec_bound_odo_e, ec_category_fatal_e, + "EC-BOUND-ODO", "OCCURS ... DEPENDING ON data item out of bounds" }, + { ec_bound_overflow_e, uc_category_nonfatal_e, + "EC-BOUND-OVERFLOW", + "Current capacity of dynamic-capacity table greater than expected value" }, + { ec_bound_ptr_e, uc_category_fatal_e, + "EC-BOUND-PTR", "Data-pointer contains an address that is out of bounds" }, + { ec_bound_ref_mod_e, ec_category_fatal_e, + "EC-BOUND-REF-MOD", "Reference modifier out of bounds" }, + { ec_bound_set_e, uc_category_nonfatal_e, + "EC-BOUND-SET", "Invalid use of SET to set capacity of " + "dynamic-capacity table above specified maximum" }, + { ec_bound_subscript_e, ec_category_fatal_e, + "EC-BOUND-SUBSCRIPT", "Subscript out of bounds" }, + { ec_bound_table_limit_e, uc_category_fatal_e, + "EC-BOUND-TABLE-LIMIT", + "Capacity of dynamic-capacity table would exceed implementor's maximum" }, + + { ec_data_e, ec_category_none_e, + "EC-DATA", "Data exception" }, + { ec_data_conversion_e, uc_category_nonfatal_e, + "EC-DATA-CONVERSION", + "Conversion failed because of incomplete character correspondence" }, + { ec_data_imp_e, uc_category_implementor_e, + "EC-DATA-IMP", "Implementor-defined data exception" }, + { ec_data_incompatible_e, uc_category_fatal_e, + "EC-DATA-INCOMPATIBLE", "Incompatible data exception" }, + { ec_data_not_finite_e, uc_category_fatal_e, + "EC-DATA-NOT-FINITE", + "Attempt to use a data item described with a standard floating-point usage " + "when its contents are either a NaN or a representation of infinity" }, + { ec_data_overflow_e, uc_category_fatal_e, + "EC-DATA-OVERFLOW", + "Exponent overflow during MOVE to a receiving data item described with a " + "standard floating-point usage" }, + { ec_data_ptr_null_e, uc_category_fatal_e, + "EC-DATA-PTR-NULL", + "Based item data-pointer is set to NULL when referenced" }, + + { ec_external_data_mismatch_e, uc_category_fatal_e, + "EC-EXTERNAL-DATA-MISMATCH", + "File referencing control item conflict because the linage, " + "file status or relative key references are not to the same item " }, + { ec_external_file_mismatch_e, uc_category_fatal_e, + "EC-EXTERNAL-FILE-MISMATCH", + "File control SELECT statements are not compatible" }, + { ec_external_format_conflict_e, uc_category_fatal_e, + "EC-EXTERNAL-FORMAT-CONFLICT", + "Data definitions definitions do not conform" }, + + { ec_flow_e, ec_category_none_e, + "EC-FLOW", "Execution control flow violation" }, + { ec_flow_global_exit_e, uc_category_fatal_e, + "EC-FLOW-GLOBAL-EXIT", "EXIT PROGRAM in a global Declarative" }, + { ec_flow_global_goback_e, uc_category_fatal_e, + "EC-FLOW-GLOBAL-GOBACK", "GOBACK in a global declarative" }, + { ec_flow_imp_e, uc_category_implementor_e, + "EC-FLOW-IMP", "Implementor-defined control flow violation" }, + { ec_flow_release_e, uc_category_fatal_e, + "EC-FLOW-RELEASE", "RELEASE not in range of SORT" }, + { ec_flow_report_e, uc_category_fatal_e, + "EC-FLOW-REPORT", + "GENERATE, INITIATE, or TERMINATE during USE BEFORE REPORTING declarative" }, + { ec_flow_return_e, uc_category_fatal_e, + "EC-FLOW-RETURN", "RETURN not in range of MERGE or SORT" }, + { ec_flow_search_e, uc_category_fatal_e, + "EC-FLOW-SEARCH", + "Invalid use of SET to change capacity of dynamic- capacity table during " + "SEARCH of same table" }, + { ec_flow_use_e, uc_category_fatal_e, + "EC-FLOW-USE", "A USE statement caused another to be executed" }, + + { ec_function_e, ec_category_none_e, + "EC-FUNCTION", "Function exception" }, + { ec_function_not_found_e, uc_category_fatal_e, + "EC-FUNCTION-NOT-FOUND", + "Function not found or function pointer does not point to a function" }, + { ec_function_ptr_invalid_e, uc_category_fatal_e, + "EC-FUNCTION-PTR-INVALID", "Signature mismatch" }, + { ec_function_ptr_null_e, uc_category_fatal_e, + "EC-FUNCTION-PTR-NULL", + "Function pointer used in calling a function is NULL" }, + + { ec_io_e, ec_category_none_e, + "EC-IO", "Input-output exception" }, + { ec_io_at_end_e, uc_category_nonfatal_e, + "EC-I-O-AT-END", "I-O status 1x" }, + { ec_io_eop_e, uc_category_nonfatal_e, + "EC-I-O-EOP", "An end of page condition occurred" }, + { ec_io_eop_overflow_e, uc_category_nonfatal_e, + "EC-I-O-EOP-OVERFLOW", "A page overflow condition occurred" }, + { ec_io_file_sharing_e, uc_category_nonfatal_e, + "EC-I-O-FILE-SHARING", "I-O status 6x" }, + { ec_io_imp_e, uc_category_implementor_e, + "EC-I-O-IMP", "I-O status 9x" }, + { ec_io_invalid_key_e, uc_category_nonfatal_e, + "EC-I-O-INVALID-KEY", "I-O status 2x" }, + { ec_io_linage_e, uc_category_fatal_e, + "EC-I-O-LINAGE", + "The value of a data item referenced in the LINAGE clause is not within " + "the required range" }, + { ec_io_logic_error_e, uc_category_fatal_e, + "EC-I-O-LOGIC-ERROR", "I-O status 4x" }, + { ec_io_permanent_error_e, uc_category_fatal_e, + "EC-I-O-PERMANENT-ERROR", "I-O status 3x" }, + { ec_io_record_operation_e, uc_category_nonfatal_e, + "EC-I-O-RECORD-OPERATION", "I-O status 5x" }, + + { ec_imp_e, ec_category_none_e, + "EC-IMP", "Implementor-defined exception condition" }, + + { ec_imp_suffix_e, ec_category_none_e, + "EC-IMP-SUFFIX", "Imp" }, + + { ec_locale_e, ec_category_none_e, + "EC-LOCALE", "Any locale related exception" }, + { ec_locale_imp_e, uc_category_implementor_e, + "EC-LOCALE-IMP", "Implementor-defined locale related exception" }, + { ec_locale_incompatible_e, uc_category_fatal_e, + "EC-LOCALE-INCOMPATIBLE", + "The referenced locale does not specify the expected characters in " + "LC_COLLATE" }, + { ec_locale_invalid_e, uc_category_fatal_e, + "EC-LOCALE-INVALID", "Locale content is invalid or incomplete" }, + { ec_locale_invalid_ptr_e, uc_category_fatal_e, + "EC-LOCALE-INVALID-PTR", "Pointer does not reference a saved locale" }, + { ec_locale_missing_e, uc_category_fatal_e, + "EC-LOCALE-MISSING", "The specified locale is not available" }, + { ec_locale_size_e, uc_category_fatal_e, + "EC-LOCALE-SIZE", "Digits were truncated in locale editing" }, + + { ec_oo_e, ec_category_none_e, + "EC-OO", "Any predefined OO related exception" }, + { ec_oo_arg_omitted_e, uc_category_fatal_e, + "EC-OO-ARG-OMITTED", "Reference to an omitted argument" }, + { ec_oo_conformance_e, uc_category_fatal_e, + "EC-OO-CONFORMANCE", "Failure for an object-view" }, + { ec_oo_exception_e, uc_category_fatal_e, + "EC-OO-EXCEPTION", "An exception object was not handled" }, + { ec_oo_imp_e, uc_category_implementor_e, + "EC-OO-IMP", "Implementor-defined OO exception" }, + { ec_oo_method_e, uc_category_fatal_e, + "EC-OO-METHOD", "Requested method is not available" }, + { ec_oo_null_e, uc_category_fatal_e, + "EC-OO-NULL", + "Method invocation was attempted with a null object reference" }, + { ec_oo_resource_e, uc_category_fatal_e, + "EC-OO-RESOURCE", "Insufficient system resources to create the object" }, + { ec_oo_universal_e, uc_category_fatal_e, + "EC-OO-UNIVERSAL", "A runtime type check failed" }, + + { ec_order_e, ec_category_none_e, + "EC-ORDER", "Ordering exception" }, + { ec_order_imp_e, uc_category_implementor_e, + "EC-ORDER-IMP", "Implementor-defined ordering exception" }, + { ec_order_not_supported_e, uc_category_fatal_e, + "EC-ORDER-NOT-SUPPORTED", + "Cultural ordering table or ordering level specified for " + "STANDARD-COMPARE function not supported" }, + + { ec_overflow_e, ec_category_none_e, + "EC-OVERFLOW", "Overflow condition" }, + { ec_overflow_imp_e, uc_category_implementor_e, + "EC-OVERFLOW-IMP", "Implementor-defined overflow condition" }, + { ec_overflow_string_e, uc_category_nonfatal_e, + "EC-OVERFLOW-STRING", "STRING overflow condition" }, + { ec_overflow_unstring_e, uc_category_nonfatal_e, + "EC-OVERFLOW-UNSTRING", "UNSTRING overflow condition" }, + + { ec_program_e, ec_category_none_e, + "EC-PROGRAM", "Inter-program communication exception" }, + { ec_program_arg_mismatch_e, uc_category_fatal_e, + "EC-PROGRAM-ARG-MISMATCH", "Parameter mismatch" }, + { ec_program_arg_omitted_e, uc_category_fatal_e, + "EC-PROGRAM-ARG-OMITTED", "A reference to an omitted argument" }, + { ec_program_cancel_active_e, uc_category_fatal_e, + "EC-PROGRAM-CANCEL-ACTIVE", "Canceled program active" }, + { ec_program_imp_e, uc_category_implementor_e, + "EC-PROGRAM-IMP", + "Implementor-defined inter-program communication exception" }, + { ec_program_not_found_e, uc_category_fatal_e, + "EC-PROGRAM-NOT-FOUND", "Called program not found" }, + { ec_program_ptr_null_e, uc_category_fatal_e, + "EC-PROGRAM-PTR-NULL", "Program-pointer used in CALL is set to NULL" }, + { ec_program_recursive_call_e, uc_category_fatal_e, + "EC-PROGRAM-RECURSIVE-CALL", "Called program active" }, + { ec_program_resources_e, uc_category_fatal_e, + "EC-PROGRAM-RESOURCES", "Resources not available for called program" }, + + { ec_raising_e, ec_category_none_e, + "EC-RAISING", "EXIT ... RAISING or GOBACK RAISING exception" }, + { ec_raising_imp_e, uc_category_implementor_e, + "EC-RAISING-IMP", + "Implementor-defined EXIT ... RAISING or GOBACK RAISING exception" }, + { ec_raising_not_specified_e, uc_category_fatal_e, + "EC-RAISING-NOT-SPECIFIED", + "EXIT ... RAISING or GOBACK RAISING an EC-USER exception condition not " + "specified in RAISING phrase of procedure division header" }, + + { ec_range_e, ec_category_none_e, + "EC-RANGE", "Range exception" }, + { ec_range_imp_e, uc_category_implementor_e, + "EC-RANGE-IMP", "Implementor-defined range exception" }, + { ec_range_index_e, uc_category_fatal_e, + "EC-RANGE-INDEX", + "Index set outside the range of values allowed by the implementor" }, + { ec_range_inspect_size_e, uc_category_fatal_e, + "EC-RANGE-INSPECT-SIZE", "Size of replace items in INSPECT differs" }, + { ec_range_invalid_e, uc_category_nonfatal_e, + "EC-RANGE-INVALID", + "Starting value of THROUGH range greater than ending value" }, + { ec_range_perform_varying_e, uc_category_fatal_e, + "EC-RANGE-PERFORM-VARYING", + "Setting of varied item in PERFORM is negative" }, + { ec_range_ptr_e, uc_category_fatal_e, + "EC-RANGE-PTR", "Pointer SET UP or DOWN is outside range" }, + { ec_range_search_index_e, uc_category_nonfatal_e, + "EC-RANGE-SEARCH-INDEX", + "No table element found in SEARCH because initial index out of range" }, + { ec_range_search_no_match_e, uc_category_nonfatal_e, + "EC-RANGE-SEARCH-NO-MATCH", + "No table element found in SEARCH because no element matched criteria" }, + + { ec_report_e, ec_category_none_e, + "EC-REPORT", "Report writer exception" }, + { ec_report_active_e, uc_category_fatal_e, + "EC-REPORT-ACTIVE", "INITIATE on an active report" }, + { ec_report_column_overlap_e, uc_category_nonfatal_e, + "EC-REPORT-COLUMN-OVERLAP", "Overlapping report items" }, + { ec_report_file_mode_e, uc_category_fatal_e, + "EC-REPORT-FILE-MODE", + "An INITIATE statement was executed for a file connector that was not " + "open in the extend or output mode" }, + { ec_report_imp_e, uc_category_implementor_e, + "EC-REPORT-IMP", "Implementor-defined report writer exception" }, + { ec_report_inactive_e, uc_category_fatal_e, + "EC-REPORT-INACTIVE", "GENERATE or TERMINATE on an inactive report" }, + { ec_report_line_overlap_e, uc_category_nonfatal_e, + "EC-REPORT-LINE-OVERLAP", "Overlapping report lines" }, + { ec_report_not_terminated_e, uc_category_nonfatal_e, + "EC-REPORT-NOT-TERMINATED", "Report file closed with active report" }, + { ec_report_page_limit_e, uc_category_nonfatal_e, + "EC-REPORT-PAGE-LIMIT", "Vertical page limit exceeded" }, + { ec_report_page_width_e, uc_category_nonfatal_e, + "EC-REPORT-PAGE-WIDTH", "Page width exceeded" }, + { ec_report_sum_size_e, uc_category_fatal_e, + "EC-REPORT-SUM-SIZE", "Overflow of sum counter" }, + { ec_report_varying_e, uc_category_fatal_e, + "EC-REPORT-VARYING", "VARYING clause expression noninteger" }, + + { ec_screen_e, ec_category_none_e, + "EC-SCREEN", "Screen handling exception" }, + { ec_screen_field_overlap_e, uc_category_nonfatal_e, + "EC-SCREEN-FIELD-OVERLAP", "Screen fields overlap" }, + { ec_screen_imp_e, uc_category_implementor_e, + "EC-SCREEN-IMP", "Implementor-defined screen handling exception" }, + { ec_screen_item_truncated_e, uc_category_nonfatal_e, + "EC-SCREEN-ITEM-TRUNCATED", "Screen field too long for line" }, + { ec_screen_line_number_e, uc_category_nonfatal_e, + "EC-SCREEN-LINE-NUMBER", + "Screen item line number exceeds terminal size" }, + { ec_screen_starting_column_e, uc_category_nonfatal_e, + "EC-SCREEN-STARTING-COLUMN", + "Screen item starting column exceeds line size" }, + + { ec_size_e, ec_category_none_e, + "EC-SIZE", "Size error exception" }, + { ec_size_address_e, uc_category_fatal_e, + "EC-SIZE-ADDRESS", "Invalid pointer arithmetic" }, + { ec_size_exponentiation_e, ec_category_fatal_e, + "EC-SIZE-EXPONENTIATION", "Exponentiation rules violated" }, + { ec_size_imp_e, uc_category_implementor_e, + "EC-SIZE-IMP", "Implementor-defined size error exception" }, + { ec_size_overflow_e, ec_category_fatal_e, + "EC-SIZE-OVERFLOW", "Arithmetic overflow in calculation" }, + { ec_size_truncation_e, ec_category_fatal_e, + "EC-SIZE-TRUNCATION", "Significant digits truncated in store" }, + { ec_size_underflow_e, ec_category_fatal_e, + "EC-SIZE-UNDERFLOW", "Floating-point underflow" }, + { ec_size_zero_divide_e, ec_category_fatal_e, + "EC-SIZE-ZERO-DIVIDE", "Division by zero" }, + + { ec_sort_merge_e, ec_category_none_e, + "EC-SORT-MERGE", "SORT or MERGE exception" }, + { ec_sort_merge_active_e, uc_category_fatal_e, + "EC-SORT-MERGE-ACTIVE", + "File SORT or MERGE executed when one is already active" }, + { ec_sort_merge_file_open_e, ec_category_fatal_e, + "EC-SORT-MERGE-FILE-OPEN", + "A USING or GIVING file is open upon execution of a SORT or MERGE" }, + { ec_sort_merge_imp_e, uc_category_implementor_e, + "EC-SORT-MERGE-IMP", + "Implementor-defined SORT or MERGE exception" }, + { ec_sort_merge_release_e, uc_category_fatal_e, + "EC-SORT-MERGE-RELEASE", "RELEASE record too long or too short" }, + { ec_sort_merge_return_e, uc_category_fatal_e, + "EC-SORT-MERGE-RETURN", "RETURN executed when at end condition exists" }, + { ec_sort_merge_sequence_e, uc_category_fatal_e, + "EC-SORT-MERGE-SEQUENCE", "Sequence error on MERGE USING file" }, + + { ec_storage_e, ec_category_none_e, + "EC-STORAGE", "Storage allocation exception" }, + { ec_storage_imp_e, uc_category_implementor_e, + "EC-STORAGE-IMP", "Implementor-defined storage allocation exception" }, + { ec_storage_not_alloc_e, uc_category_nonfatal_e, + "EC-STORAGE-NOT-ALLOC", + "The data-pointer specified in a FREE statement does not identify " + "currently allocated storage" }, + { ec_storage_not_avail_e, uc_category_nonfatal_e, + "EC-STORAGE-NOT-AVAIL", + "The amount of storage requested by an ALLOCATE statement " + "is not available"}, + { ec_user_e, ec_category_none_e, + "EC-USER", "User-defined exception condition" }, + { ec_user_suffix_e, uc_category_nonfatal_e, + "EC-USER-SUFFIX", "Level-3 user-defined exception condition" }, + + { ec_validate_e, ec_category_none_e, + "EC-VALIDATE", "VALIDATE exception" }, + { ec_validate_content_e, uc_category_nonfatal_e, + "EC-VALIDATE-CONTENT", "VALIDATE content error" }, + { ec_validate_format_e, uc_category_nonfatal_e, + "EC-VALIDATE-FORMAT", "VALIDATE format error" }, + { ec_validate_imp_e, uc_category_implementor_e, + "EC-VALIDATE-IMP", "Implementor-defined VALIDATE exception" }, + { ec_validate_relation_e, uc_category_nonfatal_e, + "EC-VALIDATE-RELATION", "VALIDATE relation error" }, + { ec_validate_varying_e, uc_category_fatal_e, + "EC-VALIDATE-VARYING", "VARYING clause expression noninteger" }, +} ; + +ec_descr_t *__gg__exception_table_end = __gg__exception_table + COUNT_OF(__gg__exception_table); + diff --git a/libgcobol/valconv.h b/libgcobol/valconv.h new file mode 100644 index 00000000000..d907e6f70ee --- /dev/null +++ b/libgcobol/valconv.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021-2025 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __VALCONV_H +#define __VALCONV_H + +extern int __gg__decimal_point ; +extern int __gg__decimal_separator ; +extern int __gg__quote_character ; +extern int __gg__low_value_character ; +extern int __gg__high_value_character ; +extern char **__gg__currency_signs ; +extern int __gg__default_currency_sign; +extern char *__gg__ct_currency_signs[256]; // Compile-time currency signs + + +// All "ordinals" are zero-based ordinals. The COBOL spec's ordinal values +// for ordinary ASCII/EBCDIC ranger from 1 to 256, so we call them zero through +// 255. We use unsigned ints so that when an custom alphabet is described, we +// can make every unmentioned character have an ordinal greater than the final +// ordinal of the custom list. +struct alphabet_state + { + unsigned short collation[256]; + unsigned char low_char; + unsigned char high_char; + }; + +extern std::unordered_map __gg__alphabet_states; + +extern "C" + { + void __gg__realloc_if_necessary(char **dest, size_t *dest_size, size_t new_size); + void __gg__alphabet_create(cbl_encoding_t encoding, + size_t alphabet_index, + unsigned char *alphabet, + int low_char, + int high_char ); + bool __gg__string_to_numeric_edited(char * const dest, + char *source, // ASCII + int rdigits, + int is_negative, + const char *picture); + void __gg__string_to_alpha_edited(char *dest, + char *source, + int slength, + char *picture); + void __gg__currency_sign_init(); + void __gg__currency_sign(int symbol, const char *sign); + void __gg__remove_trailing_zeroes(char *p); + } + +#endif